Working on new navigation controllers and model. NIHVIVO-633
This commit is contained in:
parent
1cdef7f6e4
commit
6c59f2185a
8 changed files with 332 additions and 6 deletions
|
@ -99,7 +99,7 @@
|
|||
</listener>
|
||||
|
||||
<!-- Pellet setup enables reasoning. Inferences are cached in a separate DB graph. -->
|
||||
<!-- Changing the class name sets the kindss of inferences that are materialized. -->
|
||||
<!-- Changing the class name sets the kinds of inferences that are materialized. -->
|
||||
<!-- See documentation for details. -->
|
||||
<!-- If used, must be run after JenaDataSourceSetup -->
|
||||
|
||||
|
@ -295,6 +295,15 @@
|
|||
<url-pattern>/SearchIndex</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>NavigationController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.NavigationController</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>NavigationController</servlet-name>
|
||||
<url-pattern>/nav/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>TestController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.TestController</servlet-class>
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.Individual;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.listeners.StatementListener;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.NodeIterator;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.rdf.model.Statement;
|
||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.web.DisplayVocabulary;
|
||||
|
||||
public class NavigationController extends FreeMarkerHttpServlet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log log = LogFactory.getLog(NavigationController.class.getName());
|
||||
|
||||
//private Map<Pattern,String> urlPatternToURI;
|
||||
private NavigationURLPatternListener urlPatterns;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
OntModel displayOntModel = (OntModel)config.getServletContext().getAttribute("displayOntModel");
|
||||
this.urlPatterns = new NavigationURLPatternListener( );
|
||||
displayOntModel.getBaseModel().register( urlPatterns );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBody() {
|
||||
OntModel displayOntModel = (OntModel)getServletContext().getAttribute("displayOntModel");
|
||||
OntModel jenaOntModel = (OntModel)getServletContext().getAttribute("jenaOntModel");
|
||||
|
||||
//figure out what is being requested
|
||||
Individual ind = urlPatterns.getDisplayIndividual(vreq.getPathInfo(),displayOntModel);
|
||||
Map<String,Object> values = getValues(ind, displayOntModel,jenaOntModel, getValuesFromRequest(/*?*/) );
|
||||
String template = getTemplate(ind, displayOntModel);
|
||||
|
||||
return mergeBodyToTemplate(template, values);
|
||||
}
|
||||
|
||||
private Map<String,Object>getValuesFromRequest(){
|
||||
// TODO: figure out how to get request for FreeMarkerHttpServlet.
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private String getTemplate(Individual ind, OntModel displayOntModel) {
|
||||
if( ind == null ) return "defaultBody";
|
||||
|
||||
// check vitroDisplay:requiresBodyTemplate
|
||||
displayOntModel.enterCriticalSection(Model.READ);
|
||||
StmtIterator it = displayOntModel.listStatements(ind, DisplayVocabulary.REQUIRES_BODY_TEMPLATE, (RDFNode) null);
|
||||
//NodeIterator it = ind.listPropertyValues(DisplayVocabulary.REQUIRES_BODY_TEMPLATE);
|
||||
try{
|
||||
while(it.hasNext()){
|
||||
Statement stmt = it.nextStatement();
|
||||
if( stmt.getObject().isLiteral() ){
|
||||
String template = ((Literal)stmt.getObject().as(Literal.class)).getLexicalForm();
|
||||
if( template != null && template.length() > 0 ){
|
||||
return template;
|
||||
}
|
||||
}
|
||||
}
|
||||
}finally{
|
||||
it.close();
|
||||
displayOntModel.leaveCriticalSection();
|
||||
}
|
||||
return "defaultBody";
|
||||
}
|
||||
|
||||
Map<String,Object> getValues(Individual ind, OntModel displayOntModel, OntModel assertionModel, Map<String,Object> baseValues){
|
||||
if( ind == null ) return Collections.emptyMap();
|
||||
|
||||
/* Figure out what ValueFactories are specified in the display ontology for this individual. */
|
||||
Set<ValueFactory> valueFactories = new HashSet<ValueFactory>();
|
||||
displayOntModel.enterCriticalSection(Model.READ);
|
||||
StmtIterator stmts = ind.listProperties(DisplayVocabulary.REQUIRES_VALUES);
|
||||
try{
|
||||
while(stmts.hasNext()){
|
||||
Statement stmt = stmts.nextStatement();
|
||||
RDFNode obj = stmt.getObject();
|
||||
valueFactories.addAll(getValueFactory(obj,displayOntModel));
|
||||
}
|
||||
}finally{
|
||||
stmts.close();
|
||||
displayOntModel.leaveCriticalSection();
|
||||
}
|
||||
|
||||
/* Get values from the ValueFactories. */
|
||||
HashMap<String,Object> values = new HashMap<String,Object>();
|
||||
values.putAll(baseValues);
|
||||
for(ValueFactory vf : valueFactories){
|
||||
values.putAll( vf.getValues(assertionModel, values));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
protected Set<ValueFactory> getValueFactory( RDFNode valueNode, OntModel displayOntModel) {
|
||||
//maybe use jenabean or owl2java for this?
|
||||
if( valueNode.isResource() ){
|
||||
Resource res = (Resource)valueNode.as(Resource.class);
|
||||
Statement stmt = res.getProperty(DisplayVocabulary.JAVA_CLASS_NAME);
|
||||
if( stmt == null || !stmt.getObject().isLiteral() ){
|
||||
log.debug("Cannot build value factory: java class was " + stmt.getObject());
|
||||
return Collections.emptySet();
|
||||
}
|
||||
String javaClassName = ((Literal)stmt.getObject().as(Literal.class)).getLexicalForm();
|
||||
if( javaClassName == null || javaClassName.length() == 0 ){
|
||||
log.debug("Cannot build value factory: no java class was set.");
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Class<?> clazz;
|
||||
Object newObj;
|
||||
try {
|
||||
clazz = Class.forName(javaClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.debug("Cannot build value factory: no class found for " + javaClassName);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
try {
|
||||
newObj = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
log.debug("Cannot build value factory: exception while creating object of java class " + javaClassName + " " + e.getMessage());
|
||||
return Collections.emptySet();
|
||||
}
|
||||
if( newObj instanceof ValueFactory){
|
||||
ValueFactory valueFactory = (ValueFactory)newObj;
|
||||
return Collections.singleton( valueFactory );
|
||||
}else{
|
||||
log.debug("Cannot build value factory: " + javaClassName + " does not implement " + ValueFactory.class.getName() );
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}else{
|
||||
log.debug("Cannot build value factory for " + valueNode);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
interface ValueFactory {
|
||||
void configure( Map<String,String> config);
|
||||
Map<String,Object> getValues(OntModel model, Map<String,Object> values);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTitle() {
|
||||
// TODO Auto-generated method stub
|
||||
return super.getTitle();
|
||||
}
|
||||
|
||||
private class NavigationURLPatternListener extends StatementListener {
|
||||
private Map<Pattern,String> urlPatternToURI;
|
||||
|
||||
public synchronized Map<Pattern,String> getUrlPatternToURIMap(){
|
||||
if( urlPatternToURI == null || urlPatternToURI.isEmpty() ){
|
||||
this.urlPatternToURI = buildUrlPatternToURI();
|
||||
}
|
||||
return urlPatternToURI;
|
||||
}
|
||||
|
||||
protected synchronized void invalidateURLPatternMap(){
|
||||
this.urlPatternToURI = null;
|
||||
}
|
||||
|
||||
public Individual getDisplayIndividual( String pathInfo , OntModel displayModel){
|
||||
Map<Pattern,String> map = getUrlPatternToURIMap();
|
||||
for( Pattern regex : map.keySet()){
|
||||
Matcher m = regex.matcher(pathInfo);
|
||||
if(m.matches() ){
|
||||
return displayModel.getIndividual(map.get(regex));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected synchronized Map<Pattern,String> buildUrlPatternToURI(){
|
||||
OntModel displayModel = (OntModel)getServletContext().getAttribute("displayOntModel");
|
||||
Map<Pattern,String> map = new HashMap<Pattern,String>();
|
||||
StmtIterator stmts = displayModel.listStatements(null, DisplayVocabulary.URL_MAPPING,(Literal)null);
|
||||
while(stmts.hasNext()){
|
||||
Statement stmt = stmts.nextStatement();
|
||||
if( stmt.getSubject().isURIResource() && stmt.getObject().isLiteral()){
|
||||
Resource r = (Resource)stmt.getSubject().as( Resource.class);
|
||||
Pattern regex = Pattern.compile(stmt.getLiteral().getLexicalForm());
|
||||
map.put(regex,r.getURI());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addedStatement(Statement s) {
|
||||
invalidateURLPatternMap();
|
||||
}
|
||||
@Override
|
||||
public void removedStatement(Statement s) {
|
||||
invalidateURLPatternMap();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ public class SimpleOntModelSelector implements OntModelSelector {
|
|||
private OntModel userAccountsModel;
|
||||
|
||||
private OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM;
|
||||
private OntModel displayModel;
|
||||
|
||||
/**
|
||||
* Construct an OntModelSelector with a bunch of empty models
|
||||
|
@ -116,4 +117,10 @@ public class SimpleOntModelSelector implements OntModelSelector {
|
|||
this.userAccountsModel = userAccountsModel;
|
||||
}
|
||||
|
||||
public void setDisplayModel(OntModel displayModel) {
|
||||
this.displayModel = displayModel;
|
||||
}
|
||||
public OntModel getDisplayModel(){
|
||||
return this.displayModel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import javax.servlet.ServletContextEvent;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
||||
import com.hp.hpl.jena.ontology.Individual;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
|
@ -17,7 +16,6 @@ import com.hp.hpl.jena.rdf.model.ModelFactory;
|
|||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
|
@ -61,6 +59,13 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java
|
|||
inferenceOms.setUserAccountsModel(userAccountsModel);
|
||||
unionOms.setUserAccountsModel(userAccountsModel);
|
||||
|
||||
OntModel displayModel = ontModelFromContextAttribute(sce.getServletContext(),"displayOntModel");
|
||||
OntModel displayUnionModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC,ModelFactory.createUnion(displayModel, unionModel));
|
||||
sce.getServletContext().setAttribute("displayOntModel", displayUnionModel);
|
||||
baseOms.setDisplayModel(displayModel);
|
||||
inferenceOms.setDisplayModel(displayModel);
|
||||
unionOms.setDisplayModel(displayModel);
|
||||
|
||||
sce.getServletContext().setAttribute("baseOntModel", memModel);
|
||||
WebappDaoFactory baseWadf = new WebappDaoFactoryJena(baseOms, defaultNamespace, null, null);
|
||||
sce.getServletContext().setAttribute("assertionsWebappDaoFactory",baseWadf);
|
||||
|
|
|
@ -39,6 +39,7 @@ public class JenaDataSourceSetupBase {
|
|||
protected static String USERPATH = BASE+"user/";
|
||||
protected static String SYSTEMPATH = BASE+"system/";
|
||||
protected static String AUTHPATH = BASE+"auth/";
|
||||
protected static String APPPATH = BASE+"app/";
|
||||
|
||||
String DB_USER = "jenatest"; // database user id
|
||||
String DB_PASSWD = "jenatest"; // database password
|
||||
|
@ -49,6 +50,7 @@ public class JenaDataSourceSetupBase {
|
|||
static final String JENA_INF_MODEL = "http://vitro.mannlib.cornell.edu/default/vitro-kb-inf";
|
||||
static final String JENA_USER_ACCOUNTS_MODEL = "http://vitro.mannlib.cornell.edu/default/vitro-kb-userAccounts";
|
||||
static final String JENA_APPLICATION_METADATA_MODEL = "http://vitro.mannlib.cornell.edu/default/vitro-kb-applicationMetadata";
|
||||
static final String JENA_DISPLAY_METADATA_MODEL = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata";
|
||||
|
||||
static final String DEFAULT_DEFAULT_NAMESPACE = "http://vitro.mannlib.cornell.edu/ns/default#";
|
||||
|
||||
|
|
|
@ -104,6 +104,19 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase imple
|
|||
log.error("Unable to load user accounts model from DB", t);
|
||||
}
|
||||
|
||||
// display, editing and navigation Model
|
||||
try {
|
||||
Model appDbModel = makeDBModelFromConfigurationProperties(JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC);
|
||||
if (appDbModel.size() == 0)
|
||||
readOntologyFilesInPathSet(APPPATH, sce.getServletContext(),appDbModel);
|
||||
OntModel appModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
||||
appModel.add(appDbModel);
|
||||
appModel.getBaseModel().register(new ModelSynchronizer(appDbModel));
|
||||
sce.getServletContext().setAttribute("displayOntModel", appModel);
|
||||
} catch (Throwable t) {
|
||||
log.error("Unable to load user application configuration model from DB", t);
|
||||
}
|
||||
|
||||
sce.getServletContext().setAttribute("jenaOntModel", memModel);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.web;
|
||||
|
||||
import com.hp.hpl.jena.ontology.DatatypeProperty;
|
||||
import com.hp.hpl.jena.ontology.Individual;
|
||||
import com.hp.hpl.jena.ontology.ObjectProperty;
|
||||
import com.hp.hpl.jena.ontology.OntClass;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
/**
|
||||
* Vocabulary definitions from /home/bdc34/swoop/display.rdf
|
||||
* @author Auto-generated by schemagen on 18 Jun 2010 16:57
|
||||
*/
|
||||
public class DisplayVocabulary {
|
||||
/** <p>The ontology model that holds the vocabulary terms</p> */
|
||||
private static OntModel m_model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null );
|
||||
|
||||
/** <p>The namespace of the vocabulary as a string</p> */
|
||||
public static final String NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#";
|
||||
|
||||
/** <p>The namespace of the vocabulary as a string</p>
|
||||
* @see #NS */
|
||||
public static String getURI() {return NS;}
|
||||
|
||||
/** <p>The namespace of the vocabulary as a resource</p> */
|
||||
public static final Resource NAMESPACE = m_model.createResource( NS );
|
||||
|
||||
public static final ObjectProperty REQUIRES_VALUES = m_model.createObjectProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#requiresValues" );
|
||||
|
||||
public static final ObjectProperty TO_PAGE = m_model.createObjectProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#toPage" );
|
||||
|
||||
/** <p>Java package and class name. ex edu.cornell.mannlib.vitro.webapps.functions.ExampleFunction</p> */
|
||||
public static final DatatypeProperty JAVA_CLASS_NAME = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#javaClassName" );
|
||||
|
||||
public static final DatatypeProperty MENU_POSITION = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#menuPosition" );
|
||||
|
||||
public static final DatatypeProperty PARAMETER_NAME = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#parameterName" );
|
||||
|
||||
public static final DatatypeProperty PARAMETER_VALUE = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#parameterValue" );
|
||||
|
||||
public static final DatatypeProperty REQUIRES_BODY_TEMPLATE = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#requiresBodyTemplate" );
|
||||
|
||||
/** <p>Values from HttpRequest.getPathInfo() will be mapped to values from urlMapping.</p> */
|
||||
public static final DatatypeProperty URL_MAPPING = m_model.createDatatypeProperty( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping" );
|
||||
|
||||
/** <p>This represents a menu item or other general navigation item.</p> */
|
||||
public static final OntClass NAVIGATION_ELEMENT = m_model.createClass( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#NavigationElement" );
|
||||
|
||||
/** <p>Class of pages.</p> */
|
||||
public static final OntClass PAGE = m_model.createClass( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page" );
|
||||
|
||||
//public static final Individual EVENTS = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Events", PAGE );
|
||||
|
||||
//public static final Individual EVENTS_MENU_ITEM = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#EventsMenuItem", NAVIGATION_ELEMENT );
|
||||
|
||||
//public static final Individual HOME = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Home", PAGE );
|
||||
|
||||
//public static final Individual HOME_MENU_ITEM = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#HomeMenuItem", NAVIGATION_ELEMENT );
|
||||
|
||||
//public static final Individual ORGANIZATIONS = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Organizations", PAGE );
|
||||
|
||||
//public static final Individual ORGANIZATIONS_MENU_ITEM = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#OrganizationsMenuItem", NAVIGATION_ELEMENT );
|
||||
|
||||
//public static final Individual PEOPLE = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#People", PAGE );
|
||||
|
||||
//public static final Individual PEOPLE_MENU_ITEM = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#PeopleMenuItem", NAVIGATION_ELEMENT );
|
||||
|
||||
//public static final Individual PUBLICATIONS = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Publications", PAGE );
|
||||
|
||||
//public static final Individual PUBLICATIONS_MENU_ITEM = m_model.createIndividual( "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#PublicationsMenuItem", NAVIGATION_ELEMENT );
|
||||
|
||||
}
|
1
webapp/web/templates/freemarker/body/home.ftl
Normal file
1
webapp/web/templates/freemarker/body/home.ftl
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>Welcome to VIVO</h1>
|
Loading…
Add table
Reference in a new issue