From d2792db057e291416db52524386f89bedd7d328c Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 4 Dec 2013 16:32:01 -0500 Subject: [PATCH 1/4] VIVO-614 faster model reconciliation in ABoxRecomputer --- .../vitro/webapp/reasoner/ABoxRecomputer.java | 212 +++++++----------- .../vitro/webapp/reasoner/ReasonerPlugin.java | 2 + .../vitro/webapp/reasoner/SimpleReasoner.java | 30 ++- .../webapp/reasoner/plugin/DisableSameAs.java | 6 +- .../reasoner/plugin/SimpleBridgingRule.java | 4 + .../plugin/SimplePropertyAndTypeRule.java | 4 + .../servlet/setup/SimpleReasonerSetup.java | 5 +- .../SimpleReasonerInversePropertyTest.java | 21 +- .../reasoner/SimpleReasonerSameAsTest.java | 8 +- 9 files changed, 144 insertions(+), 148 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ABoxRecomputer.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ABoxRecomputer.java index fbbc5702f..0c7bca4f1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ABoxRecomputer.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ABoxRecomputer.java @@ -107,6 +107,9 @@ public class ABoxRecomputer { } } + // don't check for existing inferences in the rebuild model + private boolean DO_CHECK = true; + /* * Recompute the entire ABox inference graph. The new * inference graph is built in a separate model and @@ -132,11 +135,13 @@ public class ABoxRecomputer { log.info("Recomputing inferences for " + individuals.size() + " individuals"); + long start = System.currentTimeMillis(); + for (String individualURI : individuals) { Resource individual = ResourceFactory.createResource(individualURI); try { - addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes); + addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes, DO_CHECK); simpleReasoner.setMostSpecificTypes(individual, inferenceRebuildModel, unknownTypes); List pluginList = simpleReasoner.getPluginList(); if (pluginList.size() > 0) { @@ -165,8 +170,11 @@ public class ABoxRecomputer { } numStmts++; - if ((numStmts % 10000) == 0) { - log.info("Still computing class subsumption ABox inferences..."); + if ((numStmts % 1000) == 0) { + log.info("Still computing class subsumption ABox inferences (" + + numStmts + "/" + individuals.size() + " individuals)"); + log.info((System.currentTimeMillis() - start) / 1000 + " ms per individual"); + start = System.currentTimeMillis(); } if (stopRequested) { @@ -275,7 +283,7 @@ public class ABoxRecomputer { log.info("Finished computing sameAs ABox inferences"); try { - if (updateInferenceModel(inferenceRebuildModel)) { + if (updateInferenceModel(inferenceRebuildModel, individuals)) { log.info("a stopRequested signal was received during updateInferenceModel. Halting Processing."); return; } @@ -365,8 +373,14 @@ public class ABoxRecomputer { } } - - protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet unknownTypes) { + + protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, + HashSet unknownTypes) { + addedABoxTypeAssertion(individual, inferenceModel, unknownTypes, true); + } + + protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, + HashSet unknownTypes, boolean checkRedundancy) { StmtIterator iter = null; @@ -376,7 +390,8 @@ public class ABoxRecomputer { while (iter.hasNext()) { Statement stmt = iter.next(); - simpleReasoner.addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes); + simpleReasoner.addedABoxTypeAssertion( + stmt, inferenceModel, unknownTypes, checkRedundancy); } } finally { if (iter != null) { @@ -388,125 +403,72 @@ public class ABoxRecomputer { /* * reconcile a set of inferences into the application inference model */ - protected boolean updateInferenceModel(Model inferenceRebuildModel) { + protected boolean updateInferenceModel(Model inferenceRebuildModel, + Collection individuals) { + + log.info("Updating ABox inference model"); + + // Remove everything from the current inference model that is not + // in the recomputed inference model + int num = 0; + scratchpadModel.enterCriticalSection(Lock.WRITE); + scratchpadModel.removeAll(); + Model rebuild = ModelFactory.createDefaultModel(); + Model existing = ModelFactory.createDefaultModel(); - log.info("Updating ABox inference model"); - Iterator iter = null; - - // Remove everything from the current inference model that is not - // in the recomputed inference model - int num = 0; - scratchpadModel.enterCriticalSection(Lock.WRITE); - scratchpadModel.removeAll(); - log.info("Updating ABox inference model (checking for outdated inferences)"); - try { - inferenceModel.enterCriticalSection(Lock.READ); - - try { - iter = listModelStatements(inferenceModel, JenaDataSourceSetupBase.JENA_INF_MODEL); - while (iter.hasNext()) { - Statement stmt = iter.next(); - if (!inferenceRebuildModel.contains(stmt)) { - scratchpadModel.add(stmt); - } - - num++; - if ((num % 10000) == 0) { - log.info("Still updating ABox inference model (checking for outdated inferences)..."); - } - - if (stopRequested) { - return true; - } - } - } finally { -// if (iter != null) { -// iter.close(); -// } - inferenceModel.leaveCriticalSection(); - } - - try { - iter = listModelStatements(scratchpadModel, SimpleReasonerSetup.JENA_INF_MODEL_SCRATCHPAD); - while (iter.hasNext()) { - Statement stmt = iter.next(); - - // skip statements with blank nodes to avoid excessive deletion - if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) { - continue; - } - - inferenceModel.enterCriticalSection(Lock.WRITE); - try { - inferenceModel.remove(stmt); - } finally { - inferenceModel.leaveCriticalSection(); - } - } - } finally { -// if (iter != null) { -// iter.close(); -// } - } - - // Add everything from the recomputed inference model that is not already - // in the current inference model to the current inference model. - try { - scratchpadModel.removeAll(); - log.info("Updating ABox inference model (adding any new inferences)"); - iter = listModelStatements(inferenceRebuildModel, SimpleReasonerSetup.JENA_INF_MODEL_REBUILD); - - while (iter.hasNext()) { - Statement stmt = iter.next(); - - inferenceModel.enterCriticalSection(Lock.READ); - try { - if (!inferenceModel.contains(stmt)) { - scratchpadModel.add(stmt); - } - } finally { - inferenceModel.leaveCriticalSection(); - } - - num++; - if ((num % 10000) == 0) { - log.info("Still updating ABox inference model (adding any new inferences)..."); - } - - if (stopRequested) { - return true; - } - } - } finally { -// if (iter != null) { -// iter.close(); -// } - } - - iter = listModelStatements(scratchpadModel, SimpleReasonerSetup.JENA_INF_MODEL_SCRATCHPAD); - try { - while (iter.hasNext()) { - Statement stmt = iter.next(); - - inferenceModel.enterCriticalSection(Lock.WRITE); - try { - inferenceModel.add(stmt); - } finally { - inferenceModel.leaveCriticalSection(); - } - } - } finally { -// if (iter != null) { -// iter.close(); -// } - } - } finally { - scratchpadModel.removeAll(); - scratchpadModel.leaveCriticalSection(); - } - - log.info("ABox inference model updated"); - return false; + long start = System.currentTimeMillis(); + + for (String individualURI : individuals) { + rebuild.removeAll(); + existing.removeAll(); + Resource subjInd = ResourceFactory.createResource(individualURI); + inferenceModel.enterCriticalSection(Lock.READ); + try { + existing.add(inferenceModel.listStatements(subjInd, null, (RDFNode) null)); + } finally { + inferenceModel.leaveCriticalSection(); + } + inferenceRebuildModel.enterCriticalSection(Lock.READ); + try { + rebuild.add(inferenceRebuildModel.listStatements(subjInd, null, (RDFNode) null)); + } finally { + inferenceRebuildModel.leaveCriticalSection(); + } + + Model retractions = existing.difference(rebuild); + Model additions = rebuild.difference(existing); + + inferenceModel.enterCriticalSection(Lock.WRITE); + try { + inferenceModel.remove(retractions); + inferenceModel.add(additions); + } finally { + inferenceModel.leaveCriticalSection(); + } + + inferenceRebuildModel.enterCriticalSection(Lock.WRITE); + try { + inferenceRebuildModel.remove(rebuild); + } finally { + inferenceRebuildModel.leaveCriticalSection(); + } + + num++; + if ((num % 1000) == 0) { + log.info("Still updating ABox inference model (" + + + num + "/" + individuals.size() + " individuals)"); + log.info((System.currentTimeMillis() - start) / 1000 + " ms per individual"); + start = System.currentTimeMillis(); + } + + if (stopRequested) { + return true; + } + + } + + log.info("ABox inference model updated"); + return false; } private Iterator listModelStatements(Model model, String graphURI) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ReasonerPlugin.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ReasonerPlugin.java index aa3ce9689..5b38ef81e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ReasonerPlugin.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/ReasonerPlugin.java @@ -12,6 +12,8 @@ public interface ReasonerPlugin { public boolean isInterestedInRemovedStatement(Statement stmt); + public boolean isConfigurationOnlyPlugin(); + public void addedABoxStatement(Statement stmt, Model aboxAssertionsModel, Model aboxInferencesModel, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index 4374f0b58..0f40e4721 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -161,6 +161,10 @@ public class SimpleReasoner extends StatementListener { public void setSameAsEnabled( boolean tf){ this.doSameAs = tf; } + + public boolean getSameAsEnabled() { + return this.doSameAs; + } /* * Performs incremental ABox reasoning based @@ -342,6 +346,12 @@ public class SimpleReasoner extends StatementListener { public void removedTBoxStatement(Statement stmt) { changedTBoxStatement(stmt, false); } + + protected void addedABoxTypeAssertion(Statement stmt, + Model inferenceModel, + HashSet unknownTypes) { + addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes, true); + } /** * Performs incremental reasoning based on a new type assertion @@ -353,7 +363,8 @@ public class SimpleReasoner extends StatementListener { */ protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, - HashSet unknownTypes) { + HashSet unknownTypes, + boolean checkRedundancy) { tboxModel.enterCriticalSection(Lock.READ); try { @@ -379,7 +390,7 @@ public class SimpleReasoner extends StatementListener { Statement infStmt = ResourceFactory.createStatement(stmt.getSubject(), RDF.type, parentClass); - addInference(infStmt,inferenceModel,true); + addInference(infStmt, inferenceModel, true, checkRedundancy); } } } else { @@ -1189,13 +1200,20 @@ public class SimpleReasoner extends StatementListener { addInference(infStmt,inferenceModel,true); } - protected void addInference(Statement infStmt, Model inferenceModel, boolean handleSameAs) { + protected void addInference(Statement infStmt, Model inferenceModel, + boolean handleSameAs) { + addInference(infStmt, inferenceModel, handleSameAs, true); + } + + protected void addInference(Statement infStmt, Model inferenceModel, + boolean handleSameAs, boolean checkRedundancy) { aboxModel.enterCriticalSection(Lock.READ); try { inferenceModel.enterCriticalSection(Lock.WRITE); try { - if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) { + if (!checkRedundancy + || (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt))) { inferenceModel.add(infStmt); } @@ -1730,9 +1748,7 @@ public class SimpleReasoner extends StatementListener { log.info("ending DeltaComputer.run. batchMode = " + batchMode); } - } - - + } /** * Utility method for logging diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java index 009f0b409..1452f55cf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/DisableSameAs.java @@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; /** * Disables sameAs in associated SimpleReasoner. */ -public abstract class DisableSameAs implements ReasonerPlugin { +public class DisableSameAs implements ReasonerPlugin { private static final Log log = LogFactory.getLog(DisableSameAs.class); @@ -27,6 +27,10 @@ public abstract class DisableSameAs implements ReasonerPlugin { log.info("owl:sameAs disabled in SimpleReasoner."); } + public boolean isConfigurationOnlyPlugin() { + return true; + } + public SimpleReasoner getSimpleReasoner() { return this.simpleReasoner; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java index 18179e0c4..6ffb1853e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimpleBridgingRule.java @@ -62,6 +62,10 @@ public abstract class SimpleBridgingRule implements ReasonerPlugin { } + public boolean isConfigurationOnlyPlugin() { + return false; + } + public boolean isInterestedInAddedStatement(Statement stmt) { return isRelevantPredicate(stmt); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java index 0518bf617..b8431a281 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/plugin/SimplePropertyAndTypeRule.java @@ -36,6 +36,10 @@ public abstract class SimplePropertyAndTypeRule implements ReasonerPlugin { INFERRED_PROP = ResourceFactory.createProperty(inferredProp); } + public boolean isConfigurationOnlyPlugin() { + return false; + } + public boolean isInterestedInAddedStatement(Statement stmt) { return (RDF.type.equals(stmt.getPredicate()) || isRelevantPredicate(stmt)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index 6d99d4c52..78470712f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -104,7 +104,10 @@ public class SimpleReasonerSetup implements ServletContextListener { ReasonerPlugin plugin = (ReasonerPlugin) Class.forName( classname).getConstructors()[0].newInstance(); plugin.setSimpleReasoner(simpleReasoner); - pluginList.add(plugin); + if (!plugin.isConfigurationOnlyPlugin()) { + pluginList.add(plugin); + log.info("adding reasoner plugin " + plugin.getClass().getName()); + } } catch(Throwable t) { ss.info(this, "Could not instantiate reasoner plugin " + classname); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java index 0003d576a..12f157725 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerInversePropertyTest.java @@ -14,6 +14,7 @@ import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread; @@ -431,10 +432,10 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { tBox.register(simpleReasonerTBoxListener); // add abox data - Resource a = aBox.createResource("http://test.vivo/a"); - Resource b = aBox.createResource("http://test.vivo/b"); - Resource c = aBox.createResource("http://test.vivo/c"); - Resource d = aBox.createResource("http://test.vivo/d"); + Resource a = aBox.createIndividual("http://test.vivo/a", OWL.Thing); + Resource b = aBox.createIndividual("http://test.vivo/b", OWL.Thing); + Resource c = aBox.createIndividual("http://test.vivo/c", OWL.Thing); + Resource d = aBox.createIndividual("http://test.vivo/d", OWL.Thing); aBox.add(a,P,b); aBox.add(c,P,d); @@ -496,8 +497,8 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { tBox.register(simpleReasonerTBoxListener); // add statements to the abox and verify inference - Resource c = aBox.createResource("http://test.vivo/c"); - Resource d = aBox.createResource("http://test.vivo/d"); + Resource c = aBox.createIndividual("http://test.vivo/c", OWL.Thing); + Resource d = aBox.createIndividual("http://test.vivo/d", OWL.Thing); aBox.add(c,P,d); Assert.assertTrue(inf.contains(d,Q,c)); @@ -555,10 +556,10 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass { aBox.register(simpleReasoner); // abox statements - Resource a = aBox.createResource("http://test.vivo/a"); - Resource b = aBox.createResource("http://test.vivo/b"); - Resource c = aBox.createResource("http://test.vivo/c"); - Resource d = aBox.createResource("http://test.vivo/d"); + Resource a = aBox.createIndividual("http://test.vivo/a", OWL.Thing); + Resource b = aBox.createIndividual("http://test.vivo/b", OWL.Thing); + Resource c = aBox.createIndividual("http://test.vivo/c", OWL.Thing); + Resource d = aBox.createIndividual("http://test.vivo/d", OWL.Thing); aBox.add(a,P,b); aBox.add(c,X,d); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java index c3b485803..81b7242f5 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerSameAsTest.java @@ -782,10 +782,10 @@ public class SimpleReasonerSameAsTest extends AbstractTestClass { aBox.register(simpleReasoner); // Individuals a, b, c and d - Resource a = aBox.createResource("http://test.vivo/a"); - Resource b = aBox.createResource("http://test.vivo/b"); - Resource c = aBox.createResource("http://test.vivo/c"); - Resource d = aBox.createResource("http://test.vivo/d"); + Resource a = aBox.createIndividual("http://test.vivo/a", OWL.Thing); + Resource b = aBox.createIndividual("http://test.vivo/b", OWL.Thing); + Resource c = aBox.createIndividual("http://test.vivo/c", OWL.Thing); + Resource d = aBox.createIndividual("http://test.vivo/d", OWL.Thing); aBox.add(a,P,c); aBox.add(a,S,literal1); From 8ab6d229a6ceafd7d930cd4a77906bc219b2cc07 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 5 Dec 2013 14:57:31 -0500 Subject: [PATCH 2/4] =?UTF-8?q?VIVO-623=20uni=C3=B3n=20domains=20and=20ran?= =?UTF-8?q?ges=20on=20object=20property=20displays?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../edit/PropertyEditController.java | 23 +++++---- .../ListPropertyWebappsController.java | 28 +++++++++-- ...ShowObjectPropertyHierarchyController.java | 47 ++++++++++++------- 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyEditController.java index 8b03779dc..b6d5dcd46 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyEditController.java @@ -27,6 +27,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; @@ -47,10 +48,12 @@ public class PropertyEditController extends BaseEditController { VitroRequest vreq = new VitroRequest(request); ObjectPropertyDao propDao = vreq.getUnfilteredWebappDaoFactory().getObjectPropertyDao(); - VClassDao vcDao = vreq.getUnfilteredWebappDaoFactory().getVClassDao(); + ObjectPropertyDao propDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getObjectPropertyDao(); + VClassDao vcDao = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); + VClassDao vcDaoWLang = vreq.getUnfilteredWebappDaoFactory().getVClassDao(); PropertyGroupDao pgDao = vreq.getUnfilteredWebappDaoFactory().getPropertyGroupDao(); - DataPropertyDao dpDao = vreq.getUnfilteredWebappDaoFactory().getDataPropertyDao(); - ObjectProperty p = (ObjectProperty)propDao.getObjectPropertyByURI(request.getParameter("uri")); + ObjectProperty p = propDao.getObjectPropertyByURI(request.getParameter("uri")); + ObjectProperty pLangNeut = propDaoLangNeut.getObjectPropertyByURI(request.getParameter("uri")); request.setAttribute("property",p); ArrayList results = new ArrayList(); @@ -119,14 +122,15 @@ public class PropertyEditController extends BaseEditController { results.add(p.getDomainPublic() == null ? "(no public label)" : p.getDomainPublic()); // column 6 String domainStr = ""; - if (p.getDomainVClassURI() != null) { - VClass domainClass = vcDao.getVClassByURI(p.getDomainVClassURI()); + if (pLangNeut.getDomainVClassURI() != null) { + VClass domainClass = vcDao.getVClassByURI(pLangNeut.getDomainVClassURI()); + VClass domainWLang = vcDaoWLang.getVClassByURI(pLangNeut.getDomainVClassURI()); if (domainClass != null && domainClass.getURI() != null && domainClass.getPickListName() != null) { try { if (domainClass.isAnonymous()) { domainStr = domainClass.getPickListName(); } else { - domainStr = ""+domainClass.getPickListName()+""; + domainStr = ""+domainWLang.getPickListName()+""; } } catch (UnsupportedEncodingException e) { log.error(e, e); @@ -136,14 +140,15 @@ public class PropertyEditController extends BaseEditController { results.add(domainStr); // column 7 String rangeStr = ""; - if (p.getRangeVClassURI() != null) { - VClass rangeClass = vcDao.getVClassByURI(p.getRangeVClassURI()); + if (pLangNeut.getRangeVClassURI() != null) { + VClass rangeClass = vcDao.getVClassByURI(pLangNeut.getRangeVClassURI()); + VClass rangeWLang = vcDaoWLang.getVClassByURI(pLangNeut.getRangeVClassURI()); if (rangeClass != null && rangeClass.getURI() != null && rangeClass.getPickListName() != null) { try { if (rangeClass.isAnonymous()) { rangeStr = rangeClass.getPickListName(); } else { - rangeStr = ""+rangeClass.getPickListName()+""; + rangeStr = ""+rangeWLang.getPickListName()+""; } } catch (UnsupportedEncodingException e) { log.error(e, e); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsController.java index 5e2213a61..09f04d5f3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyWebappsController.java @@ -59,8 +59,10 @@ public class ListPropertyWebappsController extends FreemarkerHttpServlet { String ontologyUri = vreq.getParameter("ontologyUri"); ObjectPropertyDao dao = vreq.getUnfilteredWebappDaoFactory().getObjectPropertyDao(); + ObjectPropertyDao opDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getObjectPropertyDao(); PropertyInstanceDao piDao = vreq.getLanguageNeutralWebappDaoFactory().getPropertyInstanceDao(); VClassDao vcDao = vreq.getUnfilteredWebappDaoFactory().getVClassDao(); + VClassDao vcDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); PropertyGroupDao pgDao = vreq.getUnfilteredWebappDaoFactory().getPropertyGroupDao(); String vclassURI = vreq.getParameter("vclassUri"); @@ -160,12 +162,14 @@ public class ListPropertyWebappsController extends FreemarkerHttpServlet { json += "\"data\": { \"internalName\": " + JSONUtils.quote(prop.getLocalNameWithPrefix()) + ", "; - VClass vc = (prop.getDomainVClassURI() != null) ? vcDao.getVClassByURI(prop.getDomainVClassURI()) : null; - String domainStr = (vc != null) ? vc.getPickListName() : ""; + ObjectProperty opLangNeut = opDaoLangNeut.getObjectPropertyByURI(prop.getURI()); + if(opLangNeut == null) { + opLangNeut = prop; + } + String domainStr = getVClassNameFromURI(opLangNeut.getDomainVClassURI(), vcDao, vcDaoLangNeut); json += "\"domainVClass\": " + JSONUtils.quote(domainStr) + ", " ; - vc = (prop.getRangeVClassURI() != null) ? vcDao.getVClassByURI(prop.getRangeVClassURI()) : null; - String rangeStr = (vc != null) ? vc.getPickListName() : ""; + String rangeStr = getVClassNameFromURI(opLangNeut.getRangeVClassURI(), vcDao, vcDaoLangNeut); json += "\"rangeVClass\": " + JSONUtils.quote(rangeStr) + ", " ; if (prop.getGroupURI() != null) { @@ -186,4 +190,20 @@ public class ListPropertyWebappsController extends FreemarkerHttpServlet { return new TemplateResponseValues(TEMPLATE_NAME, body); } + + private String getVClassNameFromURI(String vclassURI, VClassDao vcDao, VClassDao vcDaoLangNeut) { + if(vclassURI == null) { + return ""; + } + VClass vclass = vcDaoLangNeut.getVClassByURI(vclassURI); + if(vclass == null) { + return ""; + } + if(vclass.isAnonymous()) { + return vclass.getPickListName(); + } else { + VClass vclassWLang = vcDao.getVClassByURI(vclassURI); + return (vclassWLang != null) ? vclassWLang.getPickListName() : vclass.getPickListName(); + } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyController.java index ecd728c55..2a04ececa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowObjectPropertyHierarchyController.java @@ -39,7 +39,9 @@ public class ShowObjectPropertyHierarchyController extends FreemarkerHttpServlet private int MAXDEPTH = 5; private ObjectPropertyDao opDao = null; + private ObjectPropertyDao opDaoLangNeut = null; private VClassDao vcDao = null; + private VClassDao vcDaoLangNeut = null; private PropertyGroupDao pgDao = null; private int previous_posn = 0; @@ -75,7 +77,9 @@ public class ShowObjectPropertyHierarchyController extends FreemarkerHttpServlet body.put("propertyType", "object"); opDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao(); + opDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getObjectPropertyDao(); vcDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getVClassDao(); + vcDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); pgDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao(); String json = new String(); @@ -212,30 +216,21 @@ public class ShowObjectPropertyHierarchyController extends FreemarkerHttpServlet tempString += "\"data\": { \"internalName\": " + JSONUtils.quote( op.getLocalNameWithPrefix()) + ", "; - - VClass tmp = null; + + ObjectProperty opLangNeut = opDaoLangNeut.getObjectPropertyByURI(op.getURI()); + if(opLangNeut == null) { + opLangNeut = op; + } + String domainStr = getVClassNameFromURI(opLangNeut.getDomainVClassURI(), vcDao, vcDaoLangNeut); + String rangeStr = getVClassNameFromURI(opLangNeut.getRangeVClassURI(), vcDao, vcDaoLangNeut); try { - tempString += "\"domainVClass\": " + JSONUtils.quote( - ((tmp = vcDao.getVClassByURI( - op.getDomainVClassURI())) != null - && (tmp.getPickListName() == null)) - ? "" - : vcDao.getVClassByURI( - op.getDomainVClassURI()) - .getPickListName()) + ", " ; + tempString += "\"domainVClass\": " + JSONUtils.quote(domainStr) + ", " ; } catch (NullPointerException e) { tempString += "\"domainVClass\": \"\","; } try { - tempString += "\"rangeVClass\": " + JSONUtils.quote( - ((tmp = vcDao.getVClassByURI( - op.getRangeVClassURI())) != null - && (tmp.getPickListName() == null)) - ? "" - : vcDao.getVClassByURI( - op.getRangeVClassURI()) - .getPickListName()) + ", " ; + tempString += "\"rangeVClass\": " + JSONUtils.quote(rangeStr) + ", " ; } catch (NullPointerException e) { tempString += "\"rangeVClass\": \"\","; } @@ -252,6 +247,22 @@ public class ShowObjectPropertyHierarchyController extends FreemarkerHttpServlet } return tempString; } + + private String getVClassNameFromURI(String vclassURI, VClassDao vcDao, VClassDao vcDaoLangNeut) { + if(vclassURI == null) { + return ""; + } + VClass vclass = vcDaoLangNeut.getVClassByURI(vclassURI); + if(vclass == null) { + return ""; + } + if(vclass.isAnonymous()) { + return vclass.getPickListName(); + } else { + VClass vclassWLang = vcDao.getVClassByURI(vclassURI); + return (vclassWLang != null) ? vclassWLang.getPickListName() : vclass.getPickListName(); + } + } public static class ObjectPropertyAlphaComparator implements Comparator { From 89d4fc9228a092b06165efedea2ef3a9d5a8f4ed Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Thu, 5 Dec 2013 16:06:42 -0500 Subject: [PATCH 3/4] union domains on data property pages --- .../vitro/webapp/beans/DataProperty.java | 5 +++ .../edit/DatapropEditController.java | 30 +++++++++++----- .../ListDatatypePropertiesController.java | 26 ++++++++++++-- .../ShowDataPropertyHierarchyController.java | 36 ++++++++++++++----- .../webapp/dao/jena/DataPropertyDaoJena.java | 2 +- .../vitro/webapp/dao/jena/VClassDaoJena.java | 1 + 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java index 762e39ae0..ea243fad2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java @@ -70,6 +70,11 @@ public class DataProperty extends Property implements Comparable, public String getDomainClassURI() { return domainClassURI; } + + @Override + public String getDomainVClassURI() { + return domainClassURI; + } public void setDomainClassURI(String domainClassURI) { this.domainClassURI = domainClassURI; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java index b1e622498..bec10ecd8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java @@ -28,6 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; +import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; public class DatapropEditController extends BaseEditController { @@ -45,7 +46,13 @@ public class DatapropEditController extends BaseEditController { String datapropURI = request.getParameter("uri"); DataPropertyDao dpDao = vreq.getUnfilteredWebappDaoFactory().getDataPropertyDao(); + DataPropertyDao dpDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao(); + VClassDao vcDao = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); + VClassDao vcDaoWLang = vreq.getUnfilteredWebappDaoFactory().getVClassDao(); + DataProperty dp = dpDao.getDataPropertyByURI(datapropURI); + DataProperty pLangNeut = dpDaoLangNeut.getDataPropertyByURI(request.getParameter("uri")); + PropertyGroupDao pgDao = vreq.getUnfilteredWebappDaoFactory().getPropertyGroupDao(); ArrayList results = new ArrayList(); @@ -98,14 +105,21 @@ public class DatapropEditController extends BaseEditController { //String parentPropertyStr = "(datatype properties are not yet modeled in a property hierarchy)"; // TODO - need multiple inheritance //results.add(parentPropertyStr); - // TODO - need unionOf/intersectionOf-style domains for domain class - String domainStr=""; - try { - VClass domainClass = getWebappDaoFactory().getVClassDao().getVClassByURI(dp.getDomainClassURI()); - String domainLinkAnchor = (domainClass != null) ? domainClass.getPickListName() : dp.getDomainClassURI(); - domainStr = (dp.getDomainClassURI() == null) ? "" : ""+domainLinkAnchor+""; - } catch (UnsupportedEncodingException e) { - log.error(e, e); + String domainStr = ""; + if (pLangNeut.getDomainVClassURI() != null) { + VClass domainClass = vcDao.getVClassByURI(pLangNeut.getDomainVClassURI()); + VClass domainWLang = vcDaoWLang.getVClassByURI(pLangNeut.getDomainVClassURI()); + if (domainClass != null && domainClass.getURI() != null && domainClass.getPickListName() != null) { + try { + if (domainClass.isAnonymous()) { + domainStr = domainClass.getPickListName(); + } else { + domainStr = ""+domainWLang.getPickListName()+""; + } + } catch (UnsupportedEncodingException e) { + log.error(e, e); + } + } } results.add(domainStr); // column 6 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesController.java index 6272cd553..bd0243fd3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListDatatypePropertiesController.java @@ -20,6 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.Datatype; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -57,7 +58,9 @@ public class ListDatatypePropertiesController extends FreemarkerHttpServlet { String ontologyUri = vreq.getParameter("ontologyUri"); DataPropertyDao dao = vreq.getUnfilteredWebappDaoFactory().getDataPropertyDao(); + DataPropertyDao dpDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao(); VClassDao vcDao = vreq.getUnfilteredWebappDaoFactory().getVClassDao(); + VClassDao vcDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); DatatypeDao dDao = vreq.getUnfilteredWebappDaoFactory().getDatatypeDao(); PropertyGroupDao pgDao = vreq.getUnfilteredWebappDaoFactory().getPropertyGroupDao(); @@ -132,8 +135,11 @@ public class ListDatatypePropertiesController extends FreemarkerHttpServlet { } } */ - VClass vc = (prop.getDomainClassURI() != null) ? vcDao.getVClassByURI(prop.getDomainClassURI()) : null; - String domainStr = (vc != null) ? vc.getPickListName() : ""; + DataProperty dpLangNeut = dpDaoLangNeut.getDataPropertyByURI(prop.getURI()); + if(dpLangNeut == null) { + dpLangNeut = prop; + } + String domainStr = getVClassNameFromURI(dpLangNeut.getDomainVClassURI(), vcDao, vcDaoLangNeut); json += "\"domainVClass\": " + JSONUtils.quote(domainStr) + ", " ; Datatype rangeDatatype = dDao.getDatatypeByURI(prop.getRangeDatatypeURI()); @@ -156,4 +162,20 @@ public class ListDatatypePropertiesController extends FreemarkerHttpServlet { } return new TemplateResponseValues(TEMPLATE_NAME, body); } + + private String getVClassNameFromURI(String vclassURI, VClassDao vcDao, VClassDao vcDaoLangNeut) { + if(vclassURI == null) { + return ""; + } + VClass vclass = vcDaoLangNeut.getVClassByURI(vclassURI); + if(vclass == null) { + return ""; + } + if(vclass.isAnonymous()) { + return vclass.getPickListName(); + } else { + VClass vclassWLang = vcDao.getVClassByURI(vclassURI); + return (vclassWLang != null) ? vclassWLang.getPickListName() : vclass.getPickListName(); + } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyController.java index e37d461ba..1f8b58cff 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ShowDataPropertyHierarchyController.java @@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.Datatype; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -40,7 +41,9 @@ public class ShowDataPropertyHierarchyController extends FreemarkerHttpServlet { private int MAXDEPTH = 5; private DataPropertyDao dpDao = null; + private DataPropertyDao dpDaoLangNeut = null; private VClassDao vcDao = null; + private VClassDao vcDaoLangNeut = null; private PropertyGroupDao pgDao = null; private DatatypeDao dDao = null; @@ -77,7 +80,9 @@ public class ShowDataPropertyHierarchyController extends FreemarkerHttpServlet { body.put("propertyType", "data"); dpDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getDataPropertyDao(); + dpDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao(); vcDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getVClassDao(); + vcDaoLangNeut = vreq.getLanguageNeutralWebappDaoFactory().getVClassDao(); pgDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao(); dDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getDatatypeDao(); @@ -217,15 +222,14 @@ public class ShowDataPropertyHierarchyController extends FreemarkerHttpServlet { tempString += "\"data\": { \"internalName\": " + JSONUtils.quote( dp.getPickListName()) + ", "; - VClass tmp = null; + DataProperty dpLangNeut = dpDaoLangNeut.getDataPropertyByURI(dp.getURI()); + if(dpLangNeut == null) { + dpLangNeut = dp; + } + String domainStr = getVClassNameFromURI(dpLangNeut.getDomainVClassURI(), vcDao, vcDaoLangNeut); + try { - tempString += "\"domainVClass\": " + JSONUtils.quote( - ((tmp = vcDao.getVClassByURI(dp.getDomainClassURI())) != null - && (tmp.getPickListName() == null)) - ? "" - : vcDao.getVClassByURI( - dp.getDomainClassURI()) - .getPickListName()) + ", " ; + tempString += "\"domainVClass\": " + JSONUtils.quote(domainStr) + ", " ; } catch (NullPointerException e) { tempString += "\"domainVClass\": \"\","; } @@ -249,4 +253,20 @@ public class ShowDataPropertyHierarchyController extends FreemarkerHttpServlet { return tempString; } + private String getVClassNameFromURI(String vclassURI, VClassDao vcDao, VClassDao vcDaoLangNeut) { + if(vclassURI == null) { + return ""; + } + VClass vclass = vcDaoLangNeut.getVClassByURI(vclassURI); + if(vclass == null) { + return ""; + } + if(vclass.isAnonymous()) { + return vclass.getPickListName(); + } else { + VClass vclassWLang = vcDao.getVClassByURI(vclassURI); + return (vclassWLang != null) ? vclassWLang.getPickListName() : vclass.getPickListName(); + } + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java index 71714fae7..674a3497e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java @@ -183,7 +183,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements dp.setPickListName(getWebappDaoFactory().makePickListName(dp)); Resource dRes = op.getDomain(); if (dRes != null) { - dp.setDomainClassURI(dRes.getURI()); + dp.setDomainClassURI(dRes.isAnon()? PSEUDO_BNODE_NS + dRes.getId().toString() : dRes.getURI()); } Resource rRes = op.getRange(); if (rRes != null) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index 3c038ba13..65b466146 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -192,6 +192,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { return getLabelOrId(cls); } } catch (Exception e) { + log.error(e, e); return "???"; } finally { cls.getModel().leaveCriticalSection(); From 0944a0d88314a0069d042695ffd1c385484d5446 Mon Sep 17 00:00:00 2001 From: hudajkhan Date: Thu, 5 Dec 2013 16:20:55 -0500 Subject: [PATCH 4/4] updates for page management issues vivo622 and 616 --- webapp/web/i18n/all.properties | 2 + webapp/web/js/menupage/pageManagementUtils.js | 45 ++++++++-- .../menupage--exampleMultipleContentTypes.ftl | 84 +++++++++++++++++++ .../freemarker/edit/forms/pageManagement.ftl | 3 +- 4 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 webapp/web/templates/freemarker/body/menupage/menupage--exampleMultipleContentTypes.ftl diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties index d201b66c9..818c27c4a 100644 --- a/webapp/web/i18n/all.properties +++ b/webapp/web/i18n/all.properties @@ -697,6 +697,7 @@ select_existing_collaborator = Select an existing Collaborator for {0} selected = Selected change_selection = change selection there_are_no_entries_for_selection = There are no entries in the system from which to select. +the_range_class_does_not_exist= The range class for this property does not exist in the system. editing_prohibited = This property is currently configured to prohibit editing. confirm_entry_deletion_from = Are you sure you want to delete the following entry from @@ -752,6 +753,7 @@ custom_template_containing_content = Custom template containing all content a_menu_page = This is a menu page menu_item_name = Menu Item Name if_blank_page_title_used = If left blank, the page title will be used. +multiple_content_default_template_error = With multiple content types, you must specify a custom template. label = label no_classes_to_select = There are no Classes in the system from which to select. diff --git a/webapp/web/js/menupage/pageManagementUtils.js b/webapp/web/js/menupage/pageManagementUtils.js index 20b95899b..54b6cfa45 100644 --- a/webapp/web/js/menupage/pageManagementUtils.js +++ b/webapp/web/js/menupage/pageManagementUtils.js @@ -205,13 +205,15 @@ var pageManagementUtils = { //Also clear custom template value so as not to submit it pageManagementUtils.clearInputs(pageManagementUtils.customTemplate); pageManagementUtils.rightSideDiv.show(); - pageManagementUtils.disablePageSave(); + //Check to see if there is already content on page, in which case save should be enabled + var pageContentSections = $("section[class='pageContent']"); + if(pageContentSections.length == 0) { + pageManagementUtils.disablePageSave(); + } }); this.customTemplateRadio.click( function() { - pageManagementUtils.customTemplate.removeClass('hidden'); - pageManagementUtils.rightSideDiv.show(); - pageManagementUtils.disablePageSave(); + pageManagementUtils.handleSelectCustomTemplate(); }); this.selfContainedTemplateRadio.click( function() { @@ -265,6 +267,16 @@ var pageManagementUtils = { }); }, + handleSelectCustomTemplate: function() { + pageManagementUtils.customTemplate.removeClass('hidden'); + pageManagementUtils.rightSideDiv.show(); + //Check to see if there is already content on page, in which case save should be enabled + var pageContentSections = $("section[class='pageContent']"); + if(pageContentSections.length == 0) { + pageManagementUtils.disablePageSave(); + } + }, + handleClickDone:function() { var selectedType = pageManagementUtils.contentTypeSelect.val(); var selectedTypeText = $("#typeSelect option:selected").text(); @@ -392,6 +404,9 @@ var pageManagementUtils = { pageManagementUtils.adjustSaveButtonHeight(); //Disable save button until the user has clicked done or cancel from the addition pageManagementUtils.disablePageSave(); + //If the default template is selected, there is already content on the page, and the user is selecting new content + //display alert message that they must select a custom template and select + pageManagementUtils.checkTemplateForMultipleContent(_this.contentTypeSelect.val()); }, disablePageSave:function() { pageManagementUtils.pageSaveButton.attr("disabled", "disabled"); @@ -430,6 +445,21 @@ var pageManagementUtils = { $el.find("select option:eq(0)").attr("selected", "selected"); }, + checkTemplateForMultipleContent:function(contentTypeSelected) { + if(contentTypeSelected != "") { + var pageContentSections = $("section[class='pageContent']"); + var selectedTemplateValue = $('input:radio[name=selectedTemplate]:checked').val(); + //A new section hasn't been added yet so check to see if there is at least one content type already on page + if(selectedTemplateValue == "default" && pageContentSections.length >= 1) { + //alert the user that they should be picking custom template instead + alert(pageManagementUtils.multipleContentWithDefaultTemplateError); + //pick custom template + $('input:radio[name=selectedTemplate][value="custom"]').attr("checked", true); + pageManagementUtils.handleSelectCustomTemplate(); + + } + } + }, //Clone content area //When adding a new content type, this function will copy the values from the new content form and generate //the content for the new section containing the content @@ -874,7 +904,12 @@ var pageManagementUtils = { if(pageContentSections.length == 0) { validationErrorMsg = pageManagementUtils.selectContentType + "
"; } else { - //For each, based on type, validate if a validation function exists + //If there are multiple content types, and the default template option is selected, then display error message + var selectedTemplateValue = $('input:radio[name=selectedTemplate]:checked').val(); + if(selectedTemplateValue == "default") { + validationErrorMsg += pageManagementUtils.multipleContentWithDefaultTemplateError; + } + //For each, based on type, validate if a validation function exists $.each(pageContentSections, function(i) { if(pageManagementUtils.processDataGetterUtils != null) { var dataGetterType = pageManagementUtils.processDataGetterUtils.selectDataGetterType($(this)); diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--exampleMultipleContentTypes.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--exampleMultipleContentTypes.ftl new file mode 100644 index 000000000..7eca46eac --- /dev/null +++ b/webapp/web/templates/freemarker/body/menupage/menupage--exampleMultipleContentTypes.ftl @@ -0,0 +1,84 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> +<#--This is an example of including multiple content types in the same template, this combines the default templates for Fixed HTML, Class groups and Solr Individuals in one template--> +<#include "menupage-checkForData.ftl"> +<#--Fixed HTML portion--> +<#--Note that variableName is employed by both the fixed html and sparql query templates, this is used to store the +actual name of the variable that is used to store either the fixed html or sparql query results. If combining fixed html +and sparql query results in a custom template, the template can utilize the actual variable name e.g. "query results" instead of how +variableName is used below.--> +<#assign htmlExists = false/> + +<#if variableName?has_content> + <#assign htmlExists = true /> + +<#if htmlExists> + ${.globals[variableName]} +<#else> + ${i18n().no_html_specified} + + +<#--Class grou section--> +<#if !noData> + + + <#include "menupage-browse.ftl"> + + ${stylesheets.add('')} + + <#include "menupage-scripts.ftl"> +<#else> + ${noDataNotification} + + +<#--Solr Individuals section--> +<#import "lib-list.ftl" as l> + +<#include "individualList-checkForData.ftl"> + +${stylesheets.add('')} + +
+

${title} +

+ <#if subtitle?has_content> +

${subtitle}

+ + + <#if (!noData)> + <#if errorMessage?has_content> +

${errorMessage}

+ <#else> + <#assign pagination> + <#if (pages?has_content && pages?size > 1)> + ${i18n().pages}: +
    + <#list pages as page> + <#if page.selected> +
  • ${page.text}
  • + <#else> + <#-- RY Ideally the urls would be generated by the controller; see search-pagedResults.ftl --> +
  • ${page.text}
  • + + +
+ + + + ${pagination} + +
    + <#list individuals as individual> +
  • + <@shortView uri=individual.uri viewContext="index" /> +
  • + +
+ + ${pagination} + + <#else> + ${noDataNotification} + +
\ No newline at end of file diff --git a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl index 108caeb5b..2d248e65f 100644 --- a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl +++ b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl @@ -189,7 +189,8 @@ supplyPrettyUrl: '${i18n().supply_url}', startUrlWithSlash: '${i18n().start_url_with_slash}', supplyTemplate: '${i18n().supply_template}', - selectContentType: '${i18n().select_content_type}' + selectContentType: '${i18n().select_content_type}', + multipleContentWithDefaultTemplateError: '${i18n().multiple_content_default_template_error}' };