From 4adba03c2a14a9f45f96c4f2e1b4984a63bd90d0 Mon Sep 17 00:00:00 2001 From: bjl23 Date: Fri, 1 Oct 2010 18:45:42 +0000 Subject: [PATCH] hand-merging revision 6005 into trunk to get around PROPFIND error --- .../webapp/controller/EntityController.java | 85 ++++++---- .../controller/jena/JenaIngestController.java | 12 +- .../webapp/dao/jena/VitroJenaModelMaker.java | 151 +++++++++++++----- .../setup/JenaDataSourceSetupBase.java | 3 +- .../setup/VitroJenaModelMakerSetup.java | 4 +- 5 files changed, 174 insertions(+), 81 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java index ad64e1146..06b04ebf7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityController.java @@ -41,7 +41,10 @@ import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; -import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; +import edu.cornell.mannlib.vitro.webapp.filestorage.FileModelHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper; +import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage; +import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQuery; import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryWrapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; @@ -99,7 +102,7 @@ public class EntityController extends VitroHttpServlet { } // If this is an uploaded file, redirect to its "alias URL". - String aliasUrl = getAliasUrlForBytestreamIndividual(req, indiv); + String aliasUrl = getAliasUrlForBytestreamIndividual(indiv); if (aliasUrl != null) { res.sendRedirect(req.getContextPath() + aliasUrl); return; @@ -175,9 +178,9 @@ public class EntityController extends VitroHttpServlet { } } } - } else { - log.error("Entity " + indiv.getURI() + " with vclass URI " + - indiv.getVClassURI() + ", no vclass with that URI exists"); + } else if (indiv.getVClassURI() != null) { + log.debug("Individual " + indiv.getURI() + " with class URI " + + indiv.getVClassURI() + ": no class found with that URI"); } if (customView!=null) { // insert test for whether a css files of the same name exists, and populate the customCss string for use when construction the header @@ -224,16 +227,10 @@ public class EntityController extends VitroHttpServlet { css += customCss; } - if( indiv.getURI().startsWith( vreq.getWebappDaoFactory().getDefaultNamespace() )){ - vreq.setAttribute("entityLinkedDataURL", indiv.getURI() + "/" + indiv.getLocalName() + ".rdf"); - } - - - // generate link to RDF representation for semantic web clients like Piggy Bank - // BJL 2008-07-16: I'm temporarily commenting this out because I forgot we need to make sure it filters out the hidden properties - // generate url for this entity - // String individualToRDF = "http://"+vreq.getServerName()+":"+vreq.getServerPort()+vreq.getContextPath()+"/entity?home=1&uri="+forURL(entity.getURI())+"&view=rdf.rdf"; - //css += ""; + if( indiv.getURI().startsWith( vreq.getWebappDaoFactory().getDefaultNamespace() )){ + String entityLinkedDataURL = indiv.getURI() + "/" + indiv.getLocalName() + ".rdf"; + vreq.setAttribute("entityLinkedDataURL", entityLinkedDataURL); + } vreq.setAttribute("css",css); vreq.setAttribute("scripts", "/templates/entity/entity_inject_head.jsp"); @@ -273,14 +270,21 @@ public class EntityController extends VitroHttpServlet { newModel.write( res.getOutputStream(), format ); } - private void doRedirect(HttpServletRequest req, HttpServletResponse res, - String redirectURL) { - // It seems like there must be a better way to do this - String hn = req.getHeader("Host"); - res.setHeader("Location", res.encodeURL( "http://" + hn + req.getContextPath() + redirectURL )); - res.setStatus(res.SC_SEE_OTHER); - } - + private void doRedirect(HttpServletRequest req, HttpServletResponse res, + String redirectURL) { + //It seems like there must be a more standard way to do a redirect in tomcat. + String hn = req.getHeader("Host"); + if (req.isSecure()) { + res.setHeader("Location", res.encodeURL("https://" + hn + + req.getContextPath() + redirectURL)); + log.info("doRedirect by using HTTPS"); + } else { + res.setHeader("Location", res.encodeURL("http://" + hn + + req.getContextPath() + redirectURL)); + log.info("doRedirect by using HTTP"); + } + res.setStatus(res.SC_SEE_OTHER); + } private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]*)$"); private static Pattern NS_PREFIX_URL = Pattern.compile("^/individual/([^/]*)/([^/]*)$"); @@ -488,16 +492,39 @@ public class EntityController extends VitroHttpServlet { * If this entity represents a File Bytestream, get its alias URL so we can * properly serve the file contents. */ - private String getAliasUrlForBytestreamIndividual(HttpServletRequest req, Individual entity) + private String getAliasUrlForBytestreamIndividual(Individual entity) throws IOException { - FileInfo fileInfo = FileInfo.instanceFromBytestreamUri(new VitroRequest( - req).getWebappDaoFactory(), entity.getURI()); - if (fileInfo == null) { - log.trace("Entity '" + entity.getURI() + "' is not a bytestream."); + if (!FileModelHelper.isFileBytestream(entity)) { + log.debug("Entity at '" + entity.getURI() + + "' is not recognized as a FileByteStream."); + return null; + } + + FileStorage fs = (FileStorage) getServletContext().getAttribute( + FileStorageSetup.ATTRIBUTE_NAME); + if (fs == null) { + log.error("Servlet context does not contain file storage at '" + + FileStorageSetup.ATTRIBUTE_NAME + "'"); + return null; + } + + String filename = fs.getFilename(entity.getURI()); + if (filename == null) { + log.error("Entity at '" + entity.getURI() + + "' is recognized as a FileByteStream, " + + "but the file system does not recognize it."); + return null; + } + + String url = FileServingHelper.getBytestreamAliasUrl(entity.getURI(), + filename); + if (url.equals(entity.getURI())) { + log.error("Entity at '" + entity.getURI() + + "' is recognized as a FileByteStream, " + + "but can't be translated to an alias URL."); return null; } - String url = fileInfo.getBytestreamAliasUrl(); log.debug("Alias URL for '" + entity.getURI() + "' is '" + url + "'"); return url; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java index 82ca7519b..480b03966 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java @@ -79,6 +79,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.Csv2Rdf; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestWorkflowProcessor; import edu.cornell.mannlib.vitro.webapp.utils.jena.WorkflowOntology; + import edu.cornell.mannlib.vitro.webapp.beans.Ontology; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; @@ -420,10 +421,10 @@ public class JenaIngestController extends BaseEditController { if(modelName!=null){ Model m = maker.getModel(modelName); ArrayList namespaceList = new ArrayList(); - ResIterator resItr = m.listResourcesWithProperty((Property)null); + ResIterator resItr = m.listResourcesWithProperty((Property)null); if(resItr!=null){ - while(resItr.hasNext()){ + while(resItr.hasNext()){ String namespace = resItr.nextResource().getNameSpace(); if(!namespaceList.contains(namespace)){ namespaceList.add(namespace); @@ -442,7 +443,6 @@ public class JenaIngestController extends BaseEditController { } else if(oldModel!=null){ doPermanentURI(oldModel,newModel,oldNamespace,newNamespace,dNamespace,maker,vreq); - request.setAttribute("title","Ingest Menu"); request.setAttribute("bodyJsp",INGEST_MENU_JSP); } @@ -736,10 +736,8 @@ public class JenaIngestController extends BaseEditController { VitroJenaSDBModelMaker vjmm = new VitroJenaSDBModelMaker(store); vreq.getSession().setAttribute("vitroJenaModelMaker",vjmm); } else { - DBConnection dbConn = new DBConnection(jdbcUrl,username,password,dbType); System.out.println("Connecting to DB at "+jdbcUrl); - ModelMaker mMaker = ModelFactory.createModelRDBMaker(dbConn); - VitroJenaModelMaker vjmm = new VitroJenaModelMaker(mMaker); + VitroJenaModelMaker vjmm = new VitroJenaModelMaker(jdbcUrl, username, password, dbType); vreq.getSession().setAttribute("vitroJenaModelMaker",vjmm); } } @@ -1052,8 +1050,6 @@ public class JenaIngestController extends BaseEditController { } } - - private String getUnusedURI(String newNamespace,WebappDaoFactory wdf){ String uri = null; String errMsg = null; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java index 00654b692..2ae071466 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java @@ -2,21 +2,32 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; +import java.sql.SQLException; import java.util.HashMap; +import java.util.List; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.db.DBConnection; +import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.GraphMaker; import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ModelReader; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.NiceIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; /** * This is a bit of a nutty idea but we'll see if it works. This can wrap an RDBModelMaker and return a memory model @@ -30,43 +41,54 @@ import com.hp.hpl.jena.util.iterator.ExtendedIterator; public class VitroJenaModelMaker implements ModelMaker { private static final Log log = LogFactory.getLog(VitroJenaModelMaker.class); - - private ModelMaker innerModelMaker = null; - private HashMap modelCache = null; + private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver"; + + private String jdbcUrl; + private String username; + private String password; + private String dbTypeStr; + private BasicDataSource dataSource; + private HashMap modelCache; private HttpServletRequest request = null; - public VitroJenaModelMaker(ModelMaker mm) { - this.innerModelMaker = mm; + public VitroJenaModelMaker(String jdbcUrl, String username, String password, String dbTypeStr) { + this.jdbcUrl = jdbcUrl; + this.username = username; + this.password = password; + this.dbTypeStr = dbTypeStr; + String driverName = ConfigurationProperties + .getProperty("VitroConnection.DataSource.driver"); + // This property is no longer used? + // We'll change it all around in 1.2 anyway. + if(driverName == null) { + driverName = DEFAULT_DRIVER; + } + this.dataSource = JenaDataSourceSetupBase.makeBasicDataSource( + driverName, + jdbcUrl, username, password); modelCache = new HashMap(); } - public VitroJenaModelMaker(ModelMaker mm, HttpServletRequest request) { - this.innerModelMaker = mm; - if (mm instanceof VitroJenaModelMaker) { - log.debug("Using cache from inner model maker "); - this.modelCache = ((VitroJenaModelMaker)mm).getCache(); - } else { - log.debug("Creating new cache"); - this.modelCache = new HashMap(); - } - this.request = request; - } - - public ModelMaker getInnerModelMaker() { - return this.innerModelMaker; - } +// public VitroJenaModelMaker(ModelMaker mm, HttpServletRequest request) { +// this.innerModelMaker = mm; +// if (mm instanceof VitroJenaModelMaker) { +// log.debug("Using cache from inner model maker "); +// this.modelCache = ((VitroJenaModelMaker)mm).getCache(); +// } else { +// log.debug("Creating new cache"); +// this.modelCache = new HashMap(); +// } +// this.request = request; +// } +// +// public ModelMaker getInnerModelMaker() { +// return this.innerModelMaker; +// } protected HashMap getCache() { return this.modelCache; } - private Model copyModelIntoMem(Model underlyingModel) { - Model memModel = ModelFactory.createDefaultModel(); - memModel.add(underlyingModel); - memModel.register(new ModelSynchronizer(underlyingModel)); - return memModel; - } - public void close() { // TODO Auto-generated method stub // So, in theory, this should close database connections and drop references @@ -81,7 +103,7 @@ public class VitroJenaModelMaker implements ModelMaker { log.debug("Returning "+arg0+" ("+cachedModel.hashCode()+") from cache"); return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.createModel(arg0)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); log.debug("Returning "+arg0+" ("+newModel.hashCode()+") from cache"); return newModel; @@ -95,22 +117,42 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.createModel(arg0,arg1)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } } public GraphMaker getGraphMaker() { - return innerModelMaker.getGraphMaker(); + throw new UnsupportedOperationException(this.getClass().getName() + + " does not support getGraphMaker()"); } public boolean hasModel(String arg0) { - return innerModelMaker.hasModel(arg0); + DBConnection conn = new DBConnection(jdbcUrl, username, password, dbTypeStr); + try { + return ModelFactory.createModelRDBMaker(conn).hasModel(arg0); + } finally { + try { + conn.close(); + } catch (SQLException sqle) { + throw new RuntimeException(sqle); + } + } } public ExtendedIterator listModels() { - return innerModelMaker.listModels(); + DBConnection conn = new DBConnection(jdbcUrl, username, password, dbTypeStr); + try { + List modelList = ModelFactory.createModelRDBMaker(conn).listModels().toList(); + return WrappedIterator.create(modelList.iterator()); + } finally { + try { + conn.close(); + } catch (SQLException sqle) { + throw new RuntimeException(sqle); + } + } } public Model openModel(String arg0, boolean arg1) { @@ -120,7 +162,7 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.openModel(arg0,arg1)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } @@ -132,7 +174,16 @@ public class VitroJenaModelMaker implements ModelMaker { m.close(); modelCache.remove(arg0); } - innerModelMaker.removeModel(arg0); + DBConnection conn = new DBConnection(jdbcUrl, username, password, dbTypeStr); + try { + ModelFactory.createModelRDBMaker(conn).removeModel(arg0); + } finally { + try { + conn.close(); + } catch (SQLException sqle) { + throw new RuntimeException(sqle); + } + } } @@ -160,13 +211,14 @@ public class VitroJenaModelMaker implements ModelMaker { } public Model createDefaultModel() { - return innerModelMaker.createDefaultModel(); + throw new UnsupportedOperationException(this.getClass().getName() + + " does not support createDefaultModel()"); } public Model createFreshModel() { - return innerModelMaker.createFreshModel(); - } + throw new UnsupportedOperationException(this.getClass().getName() + + " does not support createFreshModel()"); } @Deprecated public Model createModel() { @@ -188,7 +240,7 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.openModel(arg0)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } @@ -202,7 +254,7 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.openModelIfPresent(arg0)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } @@ -216,7 +268,7 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.getModel(arg0)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } @@ -230,7 +282,7 @@ public class VitroJenaModelMaker implements ModelMaker { if (cachedModel != null) { return cachedModel; } else { - Model newModel = copyModelIntoMem(innerModelMaker.getModel(arg0)); + Model newModel = makeDBModel(arg0); modelCache.put(arg0,newModel); return newModel; } @@ -273,5 +325,22 @@ public class VitroJenaModelMaker implements ModelMaker { } return null; } + + private OntModel makeDBModel(String jenaDbModelName) { + OntModel memCache = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + RDBGraphGenerator gen = new RDBGraphGenerator(dataSource, dbTypeStr, jenaDbModelName); + Graph g = gen.generateGraph(); + Model m = ModelFactory.createModelForGraph(g); + memCache.add(m); + memCache.register(new MemToRDBModelSynchronizer(gen)); + m.close(); + try { + gen.getConnection().close(); + } catch (SQLException e) { + log.warn("Unable to close connection for graph", e); + } + // This next piece is so that we return a fresh model object each time so we don't get cross-contamination of extra listeners, etc. + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, ModelFactory.createUnion(memCache, ModelFactory.createDefaultModel())); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index 8d6ed0516..e7bbac16d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -19,10 +19,11 @@ import com.hp.hpl.jena.rdf.model.Resource; import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator; import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph; -public class JenaDataSourceSetupBase { +public class JenaDataSourceSetupBase extends JenaBaseDaoCon { private static final Log log = LogFactory.getLog(JenaDataSourceSetupBase.class); protected final static int DEFAULT_MAXWAIT = 10000, // ms diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/VitroJenaModelMakerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/VitroJenaModelMakerSetup.java index f22e8cf52..17c6dcfdf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/VitroJenaModelMakerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/VitroJenaModelMakerSetup.java @@ -33,8 +33,8 @@ public class VitroJenaModelMakerSetup implements ServletContextListener { String password = ConfigurationProperties.getProperty("VitroConnection.DataSource.password"); DBConnection dbConn = new DBConnection(jdbcUrl, username, password, DB_TYPE); - ModelMaker mMaker = ModelFactory.createModelRDBMaker(dbConn); - VitroJenaModelMaker vjmm = new VitroJenaModelMaker(mMaker); + ; + VitroJenaModelMaker vjmm = new VitroJenaModelMaker(jdbcUrl, username, password, DB_TYPE); arg0.getServletContext().setAttribute("vitroJenaModelMaker", vjmm); log.debug("VitroJenaModelMaker set up"); } catch (Throwable t) {