Adding template variables for classgroups to menu page. NIHVIVO-632

This commit is contained in:
bdc34 2010-12-22 14:29:56 +00:00
parent 7268deff15
commit 9f80ea03ea
5 changed files with 249 additions and 32 deletions

View file

@ -4,25 +4,40 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
/**
* Controller for getting data for pages defined in the display model.
*
* This controller passes these variables to the template:
* page: a map with information about the page from the display model.
*
* See implementations of PageDataGetter for more variables.
*/
public class PageController extends FreemarkerHttpServlet{
private static final Log log = LogFactory.getLog(PageController.class);
protected final static String DEFAULT_TITLE = "Page";
protected final static String DEFAULT_BODY_TEMPLATE = "menupage.ftl";
protected static Map<String,PageDataGetter> typeToDataGetter;
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
try {
@ -30,16 +45,18 @@ public class PageController extends FreemarkerHttpServlet{
String url = vreq.getRequestURI().substring(vreq.getContextPath().length());
Map<String,Object> mapForTemplate = new HashMap<String,Object>();
String pageUri = "";
String pageUri = "";
Map<String,Object>page;
try {
pageUri = getPageUri( vreq , url );
mapForTemplate.putAll( getMapForPage( vreq, pageUri ) );
page = getMapForPage( vreq, pageUri );
mapForTemplate.put( "page", page);
} catch (Throwable th) {
return doNotFound(vreq);
}
try{
mapForTemplate.putAll( getAdditionalDataForPage( vreq, pageUri) );
mapForTemplate.putAll( getAdditionalDataForPage( vreq, pageUri, page) );
} catch( Throwable th){
log.error(th,th);
return doError(vreq);
@ -59,8 +76,42 @@ public class PageController extends FreemarkerHttpServlet{
return DEFAULT_BODY_TEMPLATE;
}
private Map<String,Object> getAdditionalDataForPage(VitroRequest vreq, String pageUri) {
return Collections.emptyMap();
protected Map<String,Object> getAdditionalDataForPage(VitroRequest vreq, String pageUri, Map<String,Object>page ) {
/* figure out if the page needs additional data added */
Map<String,Object> data = new HashMap<String,Object>();
List<String> types = (List<String>)page.get("types");
if( types != null ){
for( String type : types){
Map<String,Object> moreData = null;
try{
moreData = getAdditionalData(vreq,pageUri,page,type);
if( moreData != null)
data.putAll(moreData);
}catch(Throwable th){
log.error(th,th);
}
}
}
return data;
}
protected Map<String,Object> getAdditionalData(
VitroRequest vreq, String pageUri, Map<String, Object> page, String type) {
if(type == null || type.isEmpty())
return Collections.emptyMap();
PageDataGetter getter = typeToDataGetter.get(type);
if( getter != null ){
try{
return getter.getData(getServletContext(), vreq, pageUri, page, type);
}catch(Throwable th){
log.error(th,th);
return Collections.emptyMap();
}
} else {
return Collections.emptyMap();
}
}
private ResponseValues doError(VitroRequest vreq) {
@ -100,8 +151,67 @@ public class PageController extends FreemarkerHttpServlet{
req.setAttribute("pageURI", pageUri);
}
protected final static String DEFAULT_TITLE = "Page";
private interface PageDataGetter{
Map<String,Object> getData(ServletContext contect, VitroRequest vreq, String pageUri, Map<String, Object> page, String type );
/** Gets the type that this class applies to */
String getType();
}
/**
* This will pass these variables to the template:
* classGroupUri: uri of the classgroup associated with this page.
* vClassGroup: a data structure that is the classgroup associated with this page.
*/
static private class ClassGroupPageData implements PageDataGetter{
public Map<String,Object> getData(ServletContext context, VitroRequest vreq, String pageUri, Map<String, Object> page, String type ){
HashMap<String, Object> data = new HashMap<String,Object>();
String classGroupUri = vreq.getWebappDaoFactory().getPageDao().getClassGroupPage(pageUri);
data.put("classGroupUri", classGroupUri);
VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context);
List<VClassGroup> vcgList = vcgc.getGroups(vreq.getPortalId());
VClassGroup group = null;
for( VClassGroup vcg : vcgList){
if( vcg.getURI() != null && vcg.getURI().equals(classGroupUri)){
group = vcg;
break;
}
}
if( classGroupUri != null && !classGroupUri.isEmpty() && group == null ){
/*This could be for two reasons: one is that the classgroup doesn't exist
* The other is that there are no individuals in any of the classgroup's classes */
group = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(classGroupUri);
if( group != null ){
List<VClassGroup> vcgFullList = vreq.getWebappDaoFactory().getVClassGroupDao()
.getPublicGroupsWithVClasses(false, true, false);
for( VClassGroup vcg : vcgFullList ){
if( classGroupUri.equals(vcg.getURI()) ){
group = vcg;
break;
}
}
if( group == null ){
log.error("Cannot get classgroup '" + classGroupUri + "' for page '" + pageUri + "'");
}
}
}
data.put("vClassGroup", group); //may put null
return data;
}
public String getType(){
return DisplayVocabulary.CLASSGROUP_PAGE_TYPE;
}
}
/* register all page data getters with the PageController servlet */
static{
typeToDataGetter = new HashMap<String,PageDataGetter>();
ClassGroupPageData cgpd = new ClassGroupPageData();
typeToDataGetter.put(cgpd.getType(), cgpd);
}
//not sure what this should default to.
protected final static String DEFAULT_BODY_TEMPLATE = "menupage.ftl";
}

View file

@ -0,0 +1,22 @@
package edu.cornell.mannlib.vitro.webapp.dao;
public class DisplayVocabulary {
/* Namespace for display vocabulary */
public static final String DISPLAY_NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#";
private static final String NS = DISPLAY_NS;
/* Page types */
public static final String PAGE_TYPE = NS + "Page";
public static final String HOME_PAGE_TYPE = NS + "HomePage";
public static final String CLASSGROUP_PAGE_TYPE = NS + "ClassGroupPage";
/* Object Properties */
public static final String FOR_CLASSGROUP = NS + "forClassGroup";
/* Data Properties */
public static final String URL_MAPPING = NS + "urlMapping";
public static final String TITLE = NS + "title";
public static final String REQUIRES_BODY_TEMPLATE = NS + "requiresBodyTemplate";
}

View file

@ -20,4 +20,6 @@ public interface PageDao {
* @return
*/
String getHomePageUri();
String getClassGroupPage(String pageUri);
}

View file

@ -35,7 +35,7 @@ public class VitroVocabulary {
// an OWL DL-compatible surrogate for rdf:value for use with boxing idiom
public static final String value = vitroURI + "value";
public static final String DISPLAY = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#";
public static final String DISPLAY = DisplayVocabulary.DISPLAY_NS;
// properties found on the beans

View file

@ -10,6 +10,7 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
@ -24,50 +25,58 @@ import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.PageDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class PageDaoJena extends JenaBaseDao implements PageDao {
final static Log log = LogFactory.getLog(PageDaoJena.class);
static protected Query pageQuery;
static protected Query pageTypeQuery;
static protected Query pageMappingsQuery;
static protected Query homePageUriQuery;
static protected Query classGroupPageQuery;
static final String prefixes =
"PREFIX rdf: <" + VitroVocabulary.RDF +"> \n" +
"PREFIX rdfs: <" + VitroVocabulary.RDFS +"> \n" +
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n" +
"PREFIX display: <" + VitroVocabulary.DISPLAY +"> \n";
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n";
static final protected String pageQueryString =
prefixes + "\n" +
"SELECT ?pageUri ?bodyTemplate ?urlMapping ?title WHERE {\n" +
// " GRAPH ?g{\n"+
" ?pageUri rdf:type display:Page .\n"+
" OPTIONAL { ?pageUri display:requiresBodyTemplate ?bodyTemplate }.\n"+
" OPTIONAL { ?pageUri display:title ?title }.\n"+
" OPTIONAL { ?pageUri display:urlMapping ?urlMapping . }\n"+
// " }\n"+
" ?pageUri rdf:type <" + DisplayVocabulary.PAGE_TYPE + ">.\n"+
" OPTIONAL { ?pageUri <" + DisplayVocabulary.REQUIRES_BODY_TEMPLATE + "> ?bodyTemplate }.\n"+
" OPTIONAL { ?pageUri <" + DisplayVocabulary.TITLE + "> ?title }.\n"+
" OPTIONAL { ?pageUri <" + DisplayVocabulary.URL_MAPPING + "> ?urlMapping . }\n"+
"} \n" ;
static final protected String pageTypeQueryString =
prefixes + "\n" +
"SELECT ?type WHERE {\n" +
" ?pageUri rdf:type ?type .\n"+
"} \n" ;
static final protected String pageMappingsQueryString =
prefixes + "\n" +
"SELECT ?pageUri ?urlMapping WHERE {\n" +
// " GRAPH ?g{\n"+
" ?pageUri rdf:type display:Page .\n"+
" ?pageUri display:urlMapping ?urlMapping . \n"+
// " }\n"+
" ?pageUri rdf:type <" + DisplayVocabulary.PAGE_TYPE + "> .\n"+
" ?pageUri <" + DisplayVocabulary.URL_MAPPING + "> ?urlMapping . \n"+
"} \n" ;
static final protected String homePageUriQueryString =
prefixes + "\n" +
"SELECT ?pageUri WHERE {\n" +
// " GRAPH ?g{\n"+
" ?pageUri rdf:type display:HomePage .\n"+
// " }\n"+
" ?pageUri rdf:type <" + DisplayVocabulary.HOME_PAGE_TYPE + "> .\n"+
"} \n" ;
static final protected String classGroupPageQueryString =
prefixes + "\n" +
"SELECT ?classGroup WHERE { ?pageUri <" + DisplayVocabulary.FOR_CLASSGROUP + "> ?classGroup . }";
static{
try{
@ -76,6 +85,12 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
log.error("could not create SPARQL query for pageQuery " + th.getMessage());
log.error(pageQueryString);
}
try{
pageTypeQuery = QueryFactory.create(pageTypeQueryString);
}catch(Throwable th){
log.error("could not create SPARQL query for pageTypeQuery " + th.getMessage());
log.error(pageTypeQueryString);
}
try{
pageMappingsQuery=QueryFactory.create(pageMappingsQueryString);
}catch(Throwable th){
@ -87,6 +102,12 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
}catch(Throwable th){
log.error("could not create SPARQL query for homePageUriQuery " + th.getMessage());
log.error(homePageUriQueryString);
}
try{
classGroupPageQuery=QueryFactory.create(classGroupPageQueryString);
}catch(Throwable th){
log.error("could not create SPARQL query for classGroupPageQuery " + th.getMessage());
log.error(classGroupPageQueryString);
}
}
@ -109,17 +130,25 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
}
/**
* Gets information about a page identified by a URI.
* Gets information about a page identified by a URI.
*/
@Override
public Map<String, Object> getPage(String pageUri) {
//setup query parameters
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("pageUri", ResourceFactory.createResource(pageUri));
List<Map<String, Object>> list;
Model displayModel = getOntModelSelector().getDisplayModel();
QueryExecution qexec = QueryExecutionFactory.create(pageQuery,displayModel,initialBindings );
List<Map<String, Object>> list = executeQueryToCollection( qexec );
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(pageQuery,displayModel,initialBindings );
list = executeQueryToCollection( qexec );
qexec.close();
}finally{
displayModel.leaveCriticalSection();
}
if( list == null ){
log.error("executeQueryToCollection returned null.");
return Collections.emptyMap();
@ -128,12 +157,32 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
log.debug("no page found for " + pageUri);
return Collections.emptyMap();
}
if( list.size() > 1 ){
if( list.size() > 1 )
log.debug("multiple results found for " + pageUri + " using only the first.");
return list.get(0);
}else{
return list.get(0);
}
Map<String,Object> pageData = list.get(0);
//now get the rdf:types for the page
List<String> types = new ArrayList<String>();
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(pageTypeQuery, displayModel, initialBindings);
ResultSet rs = qexec.execSelect();
while(rs.hasNext()){
QuerySolution soln = rs.next();
types.add( nodeToString( soln.get("type" ) ));
}
qexec.close();
}finally{
displayModel.leaveCriticalSection();
}
if( list == null )
log.error("could not get types for page " + pageUri);
else
pageData.put("types", types);
return pageData;
}
@Override
@ -160,6 +209,38 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
return rv.get(0);
}
/**
* Gets a URI for display:forClassGroup for the specified page.
* Only one value is expected in the model.
* This may return null if there is no ClassGroup associated with the page.
* @param pageUri
* @return
*/
@Override
public String getClassGroupPage(String pageUri) {
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("pageUri", ResourceFactory.createResource(pageUri));
Model displayModel = getOntModelSelector().getDisplayModel();
QueryExecution qexec = QueryExecutionFactory.create( classGroupPageQuery, displayModel , initialBindings);
List<String> classGroupsForPage = new ArrayList<String>();
ResultSet resultSet = qexec.execSelect();
while(resultSet.hasNext()){
QuerySolution soln = resultSet.next();
classGroupsForPage.add( nodeToString(soln.get("classGroup")) );
}
if( classGroupsForPage.size() == 0 ){
log.debug("No classgroup info defined in display model for "+ pageUri);
return null;
}
if( classGroupsForPage.size() > 1 ){
log.error("More than one display:forClassGroup defined in display model for page " + pageUri);
}
return classGroupsForPage.get(0);
}
/* ****************************************************************************** */
/**
@ -223,6 +304,8 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
protected Map<String,Object> resultsToMap(){
return null;
}
}