NIHVIVO-1584 database agnosticism improvements

This commit is contained in:
bjl23 2011-01-13 19:44:19 +00:00
parent 1be2747d14
commit a4f67be80e
9 changed files with 304 additions and 86 deletions

View file

@ -0,0 +1,65 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet.Template;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
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.reasoner.SimpleReasoner;
import edu.cornell.mannlib.vitro.webapp.search.IndexingException;
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
public class SimpleReasonerRecomputeController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(
SimpleReasonerRecomputeController.class);
protected ResponseValues processRequest(VitroRequest vreq) {
// Due to requiresLoginLevel(), we don't get here unless logged in as DBA
if (!LoginStatusBean.getBean(vreq)
.isLoggedInAtLeast(LoginStatusBean.DBA)) {
return new RedirectResponseValues(UrlBuilder.getUrl(Route.LOGIN));
}
Map<String, Object> body = new HashMap<String, Object>();
String messageStr = "";
try {
SimpleReasoner simpleReasoner = SimpleReasoner
.getSimpleReasonerFromServletContext(
vreq.getSession().getServletContext());
if (simpleReasoner == null) {
messageStr = "No SimpleReasoner has been set up.";
} else {
if (simpleReasoner.isRecomputing()) {
messageStr =
"The SimpleReasoner is already in the process of " +
"recomputing inferences.";
} else {
simpleReasoner.recompute();
messageStr = "Recomputation of inferences started";
}
}
} catch (Exception e) {
log.error("Error recomputing inferences with SimpleReasoner", e);
body.put("errorMessage",
"There was an error while recomputing inferences: " +
e.getMessage());
return new ExceptionResponseValues(
Template.ERROR_MESSAGE.toString(), body, e);
}
body.put("message", messageStr);
return new TemplateResponseValues(Template.MESSAGE.toString(), body);
}
}

View file

@ -8,8 +8,10 @@ import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -353,6 +355,9 @@ public class JenaIngestController extends BaseEditController {
request.setAttribute("title","Ingest Menu");
request.setAttribute("bodyJsp",INGEST_MENU_JSP);
} else {
List<String> dbTypes = DatabaseType.allNames();
Collections.sort(dbTypes, new CollationSort());
request.setAttribute("dbTypes", dbTypes);
request.setAttribute("title", "Connect Jena Database");
request.setAttribute("bodyJsp",CONNECT_DB_JSP);
}
@ -863,9 +868,9 @@ public class JenaIngestController extends BaseEditController {
if ("MySQL".equals(dbType)) {
jdbcUrl += (jdbcUrl.contains("?")) ? "&" : "?";
jdbcUrl += "useUnicode=yes&characterEncoding=utf8";
dbTypeObj = DatabaseType.MySQL;
JDBC.loadDriverMySQL();
}
dbTypeObj = DatabaseType.fetch(dbType);
loadDriver(dbTypeObj);
if ("SDB".equals(tripleStore)) {
StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ;
SDBConnection conn = new SDBConnection(jdbcUrl, username, password) ;
@ -879,6 +884,26 @@ public class JenaIngestController extends BaseEditController {
}
}
private void loadDriver(DatabaseType dbType) {
if (DatabaseType.MySQL.equals(dbType)) {
JDBC.loadDriverMySQL();
} else if (DatabaseType.DB2.equals(dbType)) {
JDBC.loadDriverDB2();
} else if (DatabaseType.Derby.equals(dbType)) {
JDBC.loadDriverDerby();
} else if (DatabaseType.H2.equals(dbType)) {
JDBC.loadDriverH2();
} else if (DatabaseType.HSQLDB.equals(dbType)) {
JDBC.loadDriverHSQL();
} else if (DatabaseType.Oracle.equals(dbType)) {
JDBC.loadDriverOracle();
} else if (DatabaseType.PostgreSQL.equals(dbType)) {
JDBC.loadDriverPGSQL();
} else if (DatabaseType.SQLServer.equals(dbType)) {
JDBC.loadDriverSQLServer();
}
}
/*public void doExecuteCsv2Rdf(VitroRequest vreq) {
char[] quoteChars = {'"'};
String namespace = vreq.getParameter("namespace");
@ -1192,5 +1217,15 @@ private String doRename(String oldNamespace,String newNamespace,HttpServletRespo
return result;
}
private class CollationSort implements Comparator<String> {
Collator collator = Collator.getInstance();
public int compare(String s1, String s2) {
return collator.compare(s1, s2);
}
}
}

View file

@ -63,8 +63,10 @@ public class WebappDaoFactorySDBPrep implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
if (request.getAttribute("WebappDaoFactorySDBPrep.setup") != null) {
// don't run multiple time
if ( (!(JenaDataSourceSetupBase.isSDBActive())) ||
(request.getAttribute(
"WebappDaoFactorySDBPrep.setup") != null) ) {
// don't run multiple times or if SDB is not active
return;
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.reasoner;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -378,6 +380,28 @@ public class SimpleReasoner extends StatementListener {
inferenceModel.leaveCriticalSection();
}
}
private boolean recomputing = false;
/**
* Returns true if the reasoner is in the process of recomputing all
* inferences.
*/
public boolean isRecomputing() {
return recomputing;
}
/**
* Recompute all inferences.
*/
public synchronized void recompute() {
recomputing = true;
try {
recomputeABox();
} finally {
recomputing = false;
}
}
/*
* Recompute the entire ABox inference graph. The new
@ -388,7 +412,7 @@ public class SimpleReasoner extends StatementListener {
* memory since we are supporting very large ABox
* inference models.
*/
public void recompute(OntClass subClass, OntClass superClass) {
public synchronized void recomputeABox() {
// recompute the inferences
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
@ -571,4 +595,15 @@ public class SimpleReasoner extends StatementListener {
aboxModel.leaveCriticalSection();
}
}
}
public static SimpleReasoner getSimpleReasonerFromServletContext(
ServletContext ctx) {
Object simpleReasoner = ctx.getAttribute("simpleReasoner");
if (simpleReasoner instanceof SimpleReasoner) {
return (SimpleReasoner) simpleReasoner;
} else {
return null;
}
}
}

View file

@ -116,8 +116,10 @@ public class Entity2LuceneDoc implements Obj2DocIface{
if( ent.getRdfsLabel() != null )
value=ent.getRdfsLabel();
else{
log.debug("Skipping individual without rdfs:label " + ent.getURI());
return null;
//log.debug("Skipping individual without rdfs:label " + ent.getURI());
//return null;
log.debug("Using local name for individual with rdfs:label " + ent.getURI());
return ent.getLocalName();
}
Field name =new Field(term.NAME, value,
Field.Store.YES, Field.Index.ANALYZED);

View file

@ -40,7 +40,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
JenaDataSourceSetupBase.class);
protected final static int DEFAULT_MAXWAIT = 10000, // ms
DEFAULT_MAXACTIVE = 32,
DEFAULT_MAXACTIVE = 40,
DEFAULT_MAXIDLE = 10,
DEFAULT_TIMEBETWEENEVICTIONS = 30 * 60 * 1000, // ms
DEFAULT_TESTSPEREVICTION = 3,
@ -222,8 +222,21 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
+ maxActiveStr + " as an integer");
}
}
int maxIdleInt = (maxActiveInt > DEFAULT_MAXACTIVE)
? maxActiveInt / 4
: DEFAULT_MAXIDLE;
String maxIdleStr = ConfigurationProperties
.getProperty("VitroConnection.DataSource.pool.maxIdle");
if (!StringUtils.isEmpty(maxIdleStr)) {
try {
maxIdleInt = Integer.parseInt(maxIdleStr);
} catch (NumberFormatException nfe) {
log.error("Unable to parse connection pool maxIdle setting "
+ maxIdleStr + " as an integer");
}
}
ds.setMaxActive(maxActiveInt);
ds.setMaxIdle(DEFAULT_MAXIDLE);
ds.setMaxIdle(maxIdleInt);
ds.setMaxWait(DEFAULT_MAXWAIT);
ds.setValidationQuery(VALIDATIONQUERY);
ds.setTestOnBorrow(DEFAULT_TESTONBORROW);
@ -253,9 +266,17 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
}
protected Model makeDBModel(BasicDataSource ds,
String jenaDbModelName,
OntModelSpec jenaDbOntModelSpec,
TripleStoreType storeType) {
return makeDBModel (
ds, jenaDbModelName, jenaDbOntModelSpec, storeType, DB);
}
public static Model makeDBModel(BasicDataSource ds,
String jenaDbModelName,
OntModelSpec jenaDbOntModelSpec,
TripleStoreType storeType) {
TripleStoreType storeType, String dbType) {
Model dbModel = null;
try {
// open the db model
@ -265,7 +286,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
case RDB:
g = new RegeneratingGraph(
new RDBGraphGenerator(
ds, DB, jenaDbModelName));
ds, dbType, jenaDbModelName));
break;
case SDB:
String layoutStr = ConfigurationProperties.getProperty(
@ -399,6 +420,13 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
sce.getServletContext().setAttribute(sdbModelMaker, vsmm);
}
public static boolean isSDBActive() {
String tripleStoreTypeStr =
ConfigurationProperties.getProperty(
"VitroConnection.DataSource.tripleStoreType", "RDB");
return ("SDB".equals(tripleStoreTypeStr));
}
protected VitroJenaModelMaker getVitroJenaModelMaker(){
return vjmm;
}

View file

@ -13,34 +13,31 @@ import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase implements ServletContextListener {
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
implements ServletContextListener {
private static final Log log = LogFactory.getLog(JenaPersistentDataSourceSetup.class.getName());
private static final Log log = LogFactory.getLog(
JenaPersistentDataSourceSetup.class.getName());
public void contextInitialized(ServletContextEvent sce) {
OntModel memModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
Model dbModel = null;
boolean firstStartup = false;
Model dbModel;
OntModel memModel = ModelFactory.createOntologyModel(
this.DB_ONT_MODEL_SPEC);
try {
dbModel = makeDBModelFromConfigurationProperties(JENA_DB_MODEL, DB_ONT_MODEL_SPEC);
dbModel = makeDBModelFromConfigurationProperties(
JENA_DB_MODEL, DB_ONT_MODEL_SPEC);
ClosableIterator stmtIt = dbModel.listStatements();
try {
if (!stmtIt.hasNext()) {
firstStartup = true;
}
} finally {
stmtIt.close();
}
boolean firstStartup = isFirstStartup(dbModel);
if (firstStartup) {
long startTime = System.currentTimeMillis();
@ -48,41 +45,67 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase imple
ServletContext ctx = sce.getServletContext();
readOntologyFilesInPathSet(USERPATH, ctx, dbModel);
readOntologyFilesInPathSet(SYSTEMPATH, ctx, dbModel);
System.out.println((System.currentTimeMillis()-startTime)/1000+" seconds to populate DB");
System.out.println(
(System.currentTimeMillis() - startTime) / 1000 +
" seconds to populate DB");
}
System.out.println("Populating in-memory Jena model from persistent DB model");
long startTime = System.currentTimeMillis();
memModel.add(dbModel);
System.out.println((System.currentTimeMillis()-startTime)/1000+" seconds to synchronize models");
memModel.getBaseModel().register(new ModelSynchronizer(dbModel));
if (isSDBActive()) {
memModel = ModelFactory.createOntologyModel(
this.DB_ONT_MODEL_SPEC, dbModel);
// no in-memory copying
} else {
System.out.println(
"Populating in-memory Jena model from " +
"persistent DB model");
long startTime = System.currentTimeMillis();
memModel.add(dbModel);
System.out.println(
(System.currentTimeMillis() - startTime) / 1000 +
" seconds to synchronize models");
memModel.getBaseModel().register(
new ModelSynchronizer(dbModel));
}
} catch (OutOfMemoryError ome) {
System.out.println("**** ERROR *****");
System.out.println("Insufficient memory to load database contents for vitro.");
System.out.println("Refer to servlet container documentation about increasing heap space.");
System.out.println("Insufficient memory to load ");
System.out.println("database contents for vitro.");
System.out.println("Refer to servlet container documentation ");
System.out.println("about increasing heap space.");
System.out.println("****************");
} catch (Throwable t) {
System.out.println("Logging error details");
log.error("Unable to open db model", t);
System.out.println("**** ERROR *****");
System.out.println("Vitro unable to open Jena database model.");
System.out.println("Check that the configuration properties file has been created in WEB-INF/classes, ");
System.out.println("and that the database connection parameters are accurate. ");
System.out.println("Check that the configuration properties file ");
System.out.println("has been created in WEB-INF/classes, ");
System.out.println("and that the database connection parameters ");
System.out.println("are accurate. ");
System.out.println("****************");
}
// default inference graph
try {
Model infDbModel = makeDBModelFromConfigurationProperties(JENA_INF_MODEL, DB_ONT_MODEL_SPEC);
OntModel infModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
Model infDbModel = makeDBModelFromConfigurationProperties(
JENA_INF_MODEL, DB_ONT_MODEL_SPEC);
OntModel infModel = null;
if (infDbModel != null) {
long startTime = System.currentTimeMillis();
System.out.println("Copying cached inferences into memory");
infModel.add(infDbModel);
System.out.println((System.currentTimeMillis()-startTime)/1000+" seconds to load inferences");
if (isSDBActive()) {
infModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC, infDbModel);
} else {
infModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
long startTime = System.currentTimeMillis();
System.out.println("Copying cached inferences into memory");
infModel.add(infDbModel);
System.out.println(
(System.currentTimeMillis() - startTime) / 1000 +
" seconds to load inferences");
}
}
infModel.getBaseModel().register(new ModelSynchronizer(infDbModel));
sce.getServletContext().setAttribute("inferenceOntModel",infModel);
@ -92,7 +115,8 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase imple
// user accounts Model
try {
Model userAccountsDbModel = makeDBModelFromConfigurationProperties(JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC);
Model userAccountsDbModel = makeDBModelFromConfigurationProperties(
JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC);
if (userAccountsDbModel.size() == 0) {
readOntologyFilesInPathSet(AUTHPATH, sce.getServletContext(),
userAccountsDbModel);
@ -100,20 +124,26 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase imple
createInitialAdminUser(userAccountsDbModel);
}
}
OntModel userAccountsModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
OntModel userAccountsModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
userAccountsModel.add(userAccountsDbModel);
userAccountsModel.getBaseModel().register(new ModelSynchronizer(userAccountsDbModel));
sce.getServletContext().setAttribute("userAccountsOntModel", userAccountsModel);
userAccountsModel.getBaseModel().register(
new ModelSynchronizer(userAccountsDbModel));
sce.getServletContext().setAttribute(
"userAccountsOntModel", userAccountsModel);
} catch (Throwable t) {
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);
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);
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);
@ -125,6 +155,18 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase imple
}
private boolean isFirstStartup(Model dbModel) {
ClosableIterator stmtIt = dbModel.listStatements(
null,
RDF.type,
ResourceFactory.createResource(VitroVocabulary.PORTAL));
try {
return (!stmtIt.hasNext());
} finally {
stmtIt.close();
}
}
public void contextDestroyed(ServletContextEvent sce) {
}

View file

@ -2,6 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.sql.Connection;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
@ -14,11 +17,15 @@ import com.hp.hpl.jena.graph.Graph;
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.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc;
import com.hp.hpl.jena.sdb.sql.SDBConnection;
import com.hp.hpl.jena.sdb.store.DatabaseType;
import com.hp.hpl.jena.sdb.store.LayoutType;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph;
@ -39,7 +46,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
static final String JENA_INF_MODEL_SCRATCHPAD = "http://vitro.mannlib.cornell.edu/default/vitro-kb-inf-scratchpad";
public void contextInitialized(ServletContextEvent sce) {
try {
// set up Pellet reasoning for the TBox
@ -74,10 +81,26 @@ public class SimpleReasonerSetup implements ServletContextListener {
// set up simple reasoning for the ABox
BasicDataSource bds = JenaDataSourceSetupBase.getApplicationDataSource(sce.getServletContext());
Model rebuildModel = makeDBModel(bds, JENA_INF_MODEL_REBUILD, JenaDataSourceSetupBase.DB_ONT_MODEL_SPEC, TripleStoreType.SDB);
Model scratchModel = makeDBModel(bds, JENA_INF_MODEL_SCRATCHPAD, JenaDataSourceSetupBase.DB_ONT_MODEL_SPEC, TripleStoreType.SDB);
ServletContext ctx = sce.getServletContext();
BasicDataSource bds = JenaDataSourceSetupBase
.getApplicationDataSource(ctx);
String dbType = ConfigurationProperties.getProperty( // database type
"VitroConnection.DataSource.dbtype","MySQL");
Model rebuildModel = JenaDataSourceSetupBase.makeDBModel(
bds,
JENA_INF_MODEL_REBUILD,
JenaDataSourceSetupBase.DB_ONT_MODEL_SPEC,
TripleStoreType.SDB,
dbType);
Model scratchModel = JenaDataSourceSetupBase.makeDBModel(
bds,
JENA_INF_MODEL_SCRATCHPAD,
JenaDataSourceSetupBase.DB_ONT_MODEL_SPEC,
TripleStoreType.SDB,
dbType);
// the simple reasoner will register itself as a listener to the ABox assertions
SimpleReasoner simpleReasoner = new SimpleReasoner(unionOms.getTBoxModel(), assertionsOms.getABoxModel(), inferencesOms.getABoxModel(), rebuildModel, scratchModel);
@ -97,29 +120,4 @@ public class SimpleReasonerSetup implements ServletContextListener {
// nothing to do
}
protected Model makeDBModel(BasicDataSource ds, String jenaDbModelName, OntModelSpec jenaDbOntModelSpec, TripleStoreType storeType) {
String DB = "MySQL"; // database type
Model dbModel = null;
try {
// open the db model
try {
Graph g = null;
switch (storeType) {
case RDB:
g = new RegeneratingGraph(new RDBGraphGenerator(ds, DB, jenaDbModelName)); break;
case SDB:
StoreDesc desc = new StoreDesc(LayoutType.LayoutTripleNodesHash, DatabaseType.MySQL);
g = new RegeneratingGraph(new SDBGraphGenerator(ds, desc, jenaDbModelName)); break;
default: throw new RuntimeException ("Unsupported store type " + storeType);
}
dbModel = ModelFactory.createModelForGraph(g);
log.debug("Using database at "+ds.getUrl());
} catch (Throwable t) {
t.printStackTrace();
}
} catch (Throwable t) {
t.printStackTrace();
}
return dbModel;
}
}

View file

@ -1,6 +1,8 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<h2><a class="ingestMenu" href="ingest">Ingest Menu</a> > Connect to Jena Database</h2>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@page import="java.util.List"%><h2><a class="ingestMenu" href="ingest">Ingest Menu</a> > Connect to Jena Database</h2>
<form action="ingest" method="post">
<input type="hidden" name="action" value="connectDB"/>
@ -20,11 +22,20 @@
<label for="tripleStoreRDB">Jena RDB</label>
<input id="tripleStoreSDB" name="tripleStore" type="radio" value="SDB"/>
<label for="tripleStoreRDB">Jena SDB (hash layout)</label>
<select name="dbType">
<option value="MySQL">MySQL</option>
<c:forEach items="${requestScope.dbTypes}" var="typeName">
<c:choose>
<c:when test="${typeName eq 'MySQL'}">
<option value="${typeName}" selected="selected">${typeName}</option>
</c:when>
<c:otherwise>
<option value="${typeName}">${typeName}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
<p>database type</p>
<input id="submit" type="submit" value="Connect Database" />