diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java index 8dd42b124..1147311a4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java @@ -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 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 mapForTemplate = new HashMap(); - String pageUri = ""; + String pageUri = ""; + Mappage; 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 getAdditionalDataForPage(VitroRequest vreq, String pageUri) { - return Collections.emptyMap(); + protected Map getAdditionalDataForPage(VitroRequest vreq, String pageUri, Mappage ) { + /* figure out if the page needs additional data added */ + Map data = new HashMap(); + List types = (List)page.get("types"); + if( types != null ){ + for( String type : types){ + Map 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 getAdditionalData( + VitroRequest vreq, String pageUri, Map 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 getData(ServletContext contect, VitroRequest vreq, String pageUri, Map 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 getData(ServletContext context, VitroRequest vreq, String pageUri, Map page, String type ){ + HashMap data = new HashMap(); + String classGroupUri = vreq.getWebappDaoFactory().getPageDao().getClassGroupPage(pageUri); + data.put("classGroupUri", classGroupUri); + + VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + List 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 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(); + 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"; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java new file mode 100644 index 000000000..ba7461fda --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java @@ -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"; +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java index 160e667e6..a63ed0e01 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PageDao.java @@ -20,4 +20,6 @@ public interface PageDao { * @return */ String getHomePageUri(); + + String getClassGroupPage(String pageUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java index 3e4a3bd64..ec9bae539 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java @@ -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 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java index e178bb193..f260171f4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java @@ -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: \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 getPage(String pageUri) { //setup query parameters QuerySolutionMap initialBindings = new QuerySolutionMap(); initialBindings.add("pageUri", ResourceFactory.createResource(pageUri)); - + + List> list; Model displayModel = getOntModelSelector().getDisplayModel(); - QueryExecution qexec = QueryExecutionFactory.create(pageQuery,displayModel,initialBindings ); - List> 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 pageData = list.get(0); + + //now get the rdf:types for the page + List types = new ArrayList(); + 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 classGroupsForPage = new ArrayList(); + 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 resultsToMap(){ return null; } + + }