improvements to blank node handling in bulk deletion

This commit is contained in:
brianjlowe 2012-06-08 19:38:04 +00:00
parent cef7b583e2
commit b480cb2eea
78 changed files with 5882 additions and 605 deletions

View file

@ -0,0 +1,190 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
##################################################################
#
# Note from UCSF. Compare this to the latest in shindig-common/conf/shindig.properties
# whenever you download a new version of shindig
#
##################################################################
# Location of feature manifests (comma separated)
shindig.features.default=res://features/features.txt
# Location of container configurations (comma separated)
#shindig.containers.default=res://containers/default/container.js
shindig.containers.default=res://orng-container.js
# A file containing blacklisted gadgets.
shindig.blacklist.file=
### Inbound OAuth support
# The URL base to use for full OAuth support (three-legged)
shindig.oauth.base-url=/oauth/
shindig.oauth.authorize-action=/WEB-INF/authorize.jsp
### Outbound OAuth support
shindig.signing.state-key=
shindig.signing.key-name=
shindig.signing.key-file=
shindig.signing.global-callback-url=http://localhost:8080/shindigorng/gadgets/oauthcallback
shindig.signing.enable-signed-callbacks=true
# Set to true if you want to allow the use of 3-legged OAuth tokens when viewer != owner.
# This setting is not recommeneded for pages that allow user-controlled javascript, since
# that javascript could be used to make unauthorized requests on behalf of the viewer of the page
shindig.signing.viewer-access-tokens-enabled=false
# If enabled here, configuration values can be found in container configuration files.
shindig.locked-domain.enabled=false
# TODO: This needs to be moved to container configuration.
# Note by Eric. This is set up to now exclude everything and include nothing
shindig.content-rewrite.only-allow-excludes=false
shindig.content-rewrite.include-urls=.*
shindig.content-rewrite.exclude-urls=
shindig.content-rewrite.include-tags=body,embed,img,input,link,script,style
shindig.content-rewrite.expires=86400
shindig.content-rewrite.proxy-url=/shindigorng/gadgets/proxy?container=default&url=
shindig.content-rewrite.concat-url=/shindigorng/gadgets/concat?container=default&
shindig.content-rewrite.enable-split-js-concat=false
#
# Default set of forced libs to allow for better caching
#
# NOTE: setting this causes the EndToEnd test to fail the opensocial-templates test
shindig.gadget-rewrite.default-forced-libs=core:rpc
shindig.gadget-rewrite.default-forced-libs=
#
# Allow supported JavaScript features required by a gadget to be externalized on demand
shindig.gadget-rewrite.externalize-feature-libs=true
# Configuration for image rewriter
shindig.image-rewrite.max-inmem-bytes = 1048576
shindig.image-rewrite.max-palette-size = 256
shindig.image-rewrite.allow-jpeg-conversion = true
shindig.image-rewrite.jpeg-compression = 0.75
shindig.image-rewrite.min-threshold-bytes = 200
# Configuration for the os:Flash tag
shindig.flash.min-version = 9.0.115
# Configuration for template rewriter
shindig.template-rewrite.extension-tag-namespace=http://ns.opensocial.org/2009/extensions
# These values provide default TTLs for HTTP responses that don't use caching headers.
shindig.cache.http.defaultTtl=3600000
shindig.cache.http.negativeCacheTtl=60000
# A default refresh interval for XML files, since there is no natural way for developers to
# specify this value, and most HTTP responses don't include good cache control headers.
shindig.cache.xml.refreshInterval=300000
# Add entries in the form shindig.cache.lru.<name>.capacity to specify capacities for different
# caches when using the LruCacheProvider.
# It is highly recommended that the EhCache implementation be used instead of the LRU cache.
shindig.cache.lru.default.capacity=1000
shindig.cache.lru.expressions.capacity=1000
shindig.cache.lru.gadgetSpecs.capacity=1000
shindig.cache.lru.messageBundles.capacity=1000
shindig.cache.lru.httpResponses.capacity=10000
# The location of the EhCache configuration file.
shindig.cache.ehcache.config=res://org/apache/shindig/common/cache/ehcache/ehcacheConfig.xml
# True to enable JMX integration with cache stats
shindig.cache.ehcache.jmx.enabled=true
# true to enable JMX stats.
shindig.cache.ehcache.jmx.stats=true
# true to skip expensive encoding detection.
# if true, will only attempt to validate utf-8. Assumes all other encodings are ISO-8859-1.
shindig.http.fast-encoding-detection=true
# Configuration for the HttpFetcher
# Connection timeout, in milliseconds, for requests.
shindig.http.client.connection-timeout-ms=5000
# Maximum size, in bytes, of the object we fetched, 0 == no limit
shindig.http.client.max-object-size-bytes=0
# Strict-mode parsing for proxy and concat URIs ensures that the authority/host and path
# for the URIs match precisely what is found in the container config for it. This is
# useful where statistics and traffic routing patterns, typically in large installations,
# key on hostname (and occasionally path). Enforcing this does come at the cost that
# mismatches break, which in turn mandates that URI generation always happen in consistent
# fashion, ie. by the class itself or tightly controlled code.
shindig.uri.proxy.use-strict-parsing=false
shindig.uri.concat.use-strict-parsing=false
# Host:port of the proxy to use while fetching urls. Leave blank if proxy is
# not to be used.
org.apache.shindig.gadgets.http.basicHttpFetcherProxy=
org.apache.shindig.serviceExpirationDurationMinutes=60
#
# Older versions of shindig used 'data' in the json-rpc response format
# The spec calls for using 'result' instead, however to avoid breakage we
# allow you to set it back to the old way here
#
# valid values are
# result - new form
# data - old broken form
# both - return both fields for full compatibility
#
shindig.json-rpc.result-field=result
# Remap "Internal server error"s received from the basicHttpFetcherProxy server to
# "Bad Gateway error"s, so that it is clear to the user that the proxy server is
# the one that threw the exception.
shindig.accelerate.remapInternalServerError=true
shindig.proxy.remapInternalServerError=true
shindig.signing.key-file=/shindig/openssl/oauthkey.pem
shindig.signing.key-name=
####################################################################################
#
# Open Research Networking Gadgets Items
#
#####################################################################################
# orng.system must be set to Profiles or VIVO
#orng.system = Profiles
orng.system = VIVO
# orng.dbDriver is likely com.microsoft.sqlserver.jdbc.SQLServerDriver for Profiles and com.mysql.jdbc.Driver for VIVO
#orng.dbDriver = com.microsoft.sqlserver.jdbc.SQLServerDriver
orng.dbDriver = com.mysql.jdbc.Driver
orng.dbURL = jdbc:mysql://localhost/vitrodb
orng.dbUser = vitrodb
orng.dbPassword = vitrodb
orng.tokenservice.port = 8777
# orng.RDFConverter = elda | babel
orng.RDFConverter = elda
#orng.RDFConverter = babel
# until Profiles has RDF
orng.profilesXMLService = http://dev-profiles.ucsf.edu/api_100810/ProfileService.svc/ProfileSearch
orng.profilesRDF = true;

View file

@ -0,0 +1,28 @@
-- Add some gadgets to play with ------------------------
--
INSERT INTO `shindig_apps` (`appid`, `name`, `url`, `PersonFilterID`, `enabled`, `channels`) VALUES
(100, 'Google Search', 'http://dev-profiles.ucsf.edu/apps/GoogleSearch.xml', NULL, 1, NULL),
(101, 'Featured Presentations', 'http://dev-profiles.ucsf.edu/apps/SlideShare.xml', NULL, 1, NULL),
(102, 'Faculty Mentor', 'http://dev-profiles.ucsf.edu/apps/Mentor.xml', NULL, 1, NULL),
(103, 'Websites', 'http://dev-profiles.ucsf.edu/apps/Links.xml', NULL, 1, NULL),
(104, 'Profile List', 'http://dev-profiles.ucsf.edu/apps/ProfileListTool.xml', NULL, 1, 'JSONPersonIds'),
(105, 'Publication Export', 'http://dev-profiles.ucsf.edu/apps/PubExportTool.xml', NULL, 1, 'JSONPubMedIds'),
(106, 'RDF Test Gadget', 'http://dev-profiles.ucsf.edu/gadgets/RDFTest.xml', NULL, 1, NULL);
INSERT INTO `shindig_app_views` (`appid`, `viewer_req`, `owner_req`, `page`, `view`, `closed_width`, `open_width`, `start_closed`, `chromeId`, `display_order`) VALUES
(100, NULL, NULL, 'search', NULL, 600, 600, 1, 'gadgets-search', NULL),
(101, NULL, 'R', 'individual', 'profile', 291, 590, 1, 'gadgets-view', 3),
(101, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
(102, NULL, 'R', 'individual', 'profile', 291, 590, 1, 'gadgets-view', 2),
(102, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
(103, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
(103, NULL, 'R', 'individual', 'profile', 291, 590, 0, 'gadgets-view', 1),
(104, 'U', NULL, 'search', 'small', 160, 160, 0, 'gadgets-tools', NULL),
(104, 'U', NULL, 'gadgetDetails', 'canvas', 700, 700, 0, 'gadgets-detail', NULL),
(104, 'U', NULL, 'SimilarPeople.aspx', 'small', 160, 160, 0, 'gadgets-tools', NULL),
(104, 'U', NULL, 'individual', 'small', 160, 160, 0, 'gadgets-view', NULL),
(104, 'U', NULL, 'CoAuthors.aspx', 'small', 160, 160, 0, 'gadgets-tools', NULL),
(105, 'U', NULL, 'individual', 'small', 160, 160, 0, 'gadgets-view', NULL),
(105, 'U', NULL, 'gadgetDetails', 'canvas', 700, 700, 0, 'gadgets-detail', NULL);

View file

@ -0,0 +1,145 @@
--
-- Table structure for table `shindig_activity`
--
CREATE TABLE IF NOT EXISTS `shindig_activity` (
`activityId` int(11) NOT NULL AUTO_INCREMENT,
`userId` varchar(255) default NULL,
`appId` int(11) default NULL,
`createdDT` datetime default NULL,
`activity` text,
PRIMARY KEY (`activityId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `shindig_appdata`
--
CREATE TABLE IF NOT EXISTS `shindig_appdata` (
`userId` varchar(255) NOT NULL,
`appId` int(11) NOT NULL,
`keyname` varchar(255) NOT NULL,
`value` varchar(4000) default NULL,
`createdDT` datetime default NULL,
`updatedDT` datetime default NULL,
KEY `userId` (`userId`,`appId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `shindig_apps`
--
CREATE TABLE IF NOT EXISTS `shindig_apps` (
`appid` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`PersonFilterID` int(11) default NULL,
`enabled` tinyint(1) NOT NULL default '1',
`channels` varchar(255) default NULL,
PRIMARY KEY (`appid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `shindig_app_registry`
--
CREATE TABLE IF NOT EXISTS `shindig_app_registry` (
`appid` int(11) NOT NULL,
`personId` varchar(255) NOT NULL,
`createdDT` datetime NOT NULL,
PRIMARY KEY (`appid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `shindig_app_views`
--
CREATE TABLE IF NOT EXISTS `shindig_app_views` (
`appid` int(11) NOT NULL,
`viewer_req` char(1) default NULL,
`owner_req` char(1) default NULL,
`page` varchar(50) default NULL,
`view` varchar(50) default NULL,
`closed_width` int(11) default NULL,
`open_width` int(11) default NULL,
`start_closed` tinyint(1) default NULL,
`chromeId` varchar(50) default NULL,
`display_order` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `shindig_messages`
--
CREATE TABLE IF NOT EXISTS `shindig_messages` (
`msgId` varchar(255) NOT NULL,
`senderId` varchar(255) default NULL,
`recipientId` varchar(255) default NULL,
`coll` varchar(255) default NULL,
`title` varchar(255) default NULL,
`body` varchar(4000) default NULL,
`createdDT` datetime default NULL,
PRIMARY KEY (`msgId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
DELIMITER //
CREATE PROCEDURE shindig_registerAppPerson (uid varchar(255), aid INT, v BOOL)
BEGIN
IF (v)
THEN
INSERT INTO shindig_app_registry (appId, personId, createdDT) values (aid, uid, now());
ELSE
DELETE FROM shindig_app_registry where appId = aid AND personId = uid;
END IF;
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE shindig_upsertAppData(uid varchar(255), aid INT, kn varchar(255),v varchar(4000))
BEGIN
DECLARE cnt int;
SELECT count(*) FROM shindig_appdata WHERE userId = uid AND appId = aid and keyname = kn INTO cnt;
IF (cnt > 0)
THEN
UPDATE shindig_appdata set `value` = v, updatedDT = NOW() WHERE userId = uid AND appId = aid and keyname = kn;
ELSE
INSERT INTO shindig_appdata (userId, appId, keyname, `value`) values (uid, aid, kn, v);
END IF;
-- if keyname is VISIBLE, do more
IF (kn = 'VISIBLE' AND v = 'Y')
THEN
CALL shindig_registerAppPerson(uid, aid, 1);
ELSEIF (kn = 'VISIBLE' )
THEN
CALL shindig_registerAppPerson(uid, aid, 0);
END IF;
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE shindig_deleteAppData(uid varchar(255),aid INT, kn varchar(255))
BEGIN
DELETE FROM shindig_appdata WHERE userId = uid AND appId = aid and keyname = kn;
-- if keyname is VISIBLE, do more
IF (kn = 'VISIBLE' )
THEN
CALL shindig_registerAppPerson(uid, aid, 0);
END IF;
END //
DELIMITER ;

BIN
opensocial/shindigorng.war Normal file

Binary file not shown.

View file

@ -38,6 +38,7 @@ webapp/web/js/tiny_mce/**/*
webapp/web/js/jquery.js
webapp/web/js/jquery-ui/*
webapp/web/js/jquery_plugins/*
webapp/web/js/jquery.fix.clone.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/dojo.js
@ -173,3 +174,14 @@ webapp/src/edu/cornell/mannlib/vitro/webapp/web/antisamy-vitro-1.4.4.xml
# A kluge class derived from JarJar code. See /doc/3rd-party-licenses.txt for LICENSE file
utilities/buildutils/src/com/tonicsystems/jarjar/KlugedDepFind.java
#Public Domain
webapp/web/js/json2.js
# Part of the OpenSocial integration - What license should apply here?
webapp/src/edu/ucsf/vitro/opensocial/GadgetController.java
webapp/src/edu/ucsf/vitro/opensocial/GadgetSpec.java
webapp/src/edu/ucsf/vitro/opensocial/GadgetViewRequirements.java
webapp/src/edu/ucsf/vitro/opensocial/OpenSocialManager.java
webapp/src/edu/ucsf/vitro/opensocial/PreparedGadget.java
webapp/web/js/openSocial/shindig.js

View file

@ -1,44 +1,44 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
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 java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
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;
public class DatapropEditController extends BaseEditController {
private static final Log log = LogFactory.getLog(DatapropEditController.class.getName());
public void doPost (HttpServletRequest request, HttpServletResponse response) {
if (!isAuthorizedToDisplayPage(request, response, SimplePermission.EDIT_ONTOLOGY.ACTIONS)) {
return;
}
VitroRequest vreq = new VitroRequest(request);
public void doPost (HttpServletRequest request, HttpServletResponse response) {
if (!isAuthorizedToDisplayPage(request, response, SimplePermission.EDIT_ONTOLOGY.ACTIONS)) {
return;
}
VitroRequest vreq = new VitroRequest(request);
final int NUM_COLS=15;
@ -56,7 +56,7 @@ public class DatapropEditController extends BaseEditController {
results.add("range datatype");
results.add("group");
results.add("display tier");
results.add("display limit");
results.add("data entry limit");
results.add("example");
results.add("description");
results.add("public description");
@ -169,8 +169,8 @@ public class DatapropEditController extends BaseEditController {
}
}
request.setAttribute("equivalentProperties", eqProperties);
ApplicationBean appBean = vreq.getAppBean();
ApplicationBean appBean = vreq.getAppBean();
request.setAttribute("epoKey",epo.getKey());
request.setAttribute("datatypeProperty", dp);

View file

@ -0,0 +1,160 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.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.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.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class ListDatatypePropertiesController extends FreemarkerHttpServlet {
private static Log log = LogFactory.getLog( ListDatatypePropertiesController.class );
private static final String TEMPLATE_NAME = "siteAdmin-objectPropHierarchy.ftl";
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.EDIT_ONTOLOGY.ACTIONS;
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
try {
body.put("displayOption", "all");
body.put("pageTitle", "All Data Properties");
body.put("propertyType", "data");
String noResultsMsgStr = "No data properties found";
String ontologyUri = vreq.getParameter("ontologyUri");
DataPropertyDao dao = vreq.getFullWebappDaoFactory().getDataPropertyDao();
VClassDao vcDao = vreq.getFullWebappDaoFactory().getVClassDao();
DatatypeDao dDao = vreq.getFullWebappDaoFactory().getDatatypeDao();
PropertyGroupDao pgDao = vreq.getFullWebappDaoFactory().getPropertyGroupDao();
List<DataProperty> props = new ArrayList<DataProperty>();
if (vreq.getParameter("propsForClass") != null) {
noResultsMsgStr = "There are no data properties that apply to this class.";
Collection <DataProperty> dataProps = dao.getDataPropertiesForVClass(vreq.getParameter("vclassUri"));
Iterator<DataProperty> dataPropIt = dataProps.iterator();
HashSet<String> propURIs = new HashSet<String>();
while (dataPropIt.hasNext()) {
DataProperty dp = dataPropIt.next();
if (!(propURIs.contains(dp.getURI()))) {
propURIs.add(dp.getURI());
DataProperty prop = dao.getDataPropertyByURI(dp.getURI());
if (prop != null) {
props.add(prop);
}
}
}
} else {
props = dao.getAllDataProperties();
}
if (ontologyUri != null) {
List<DataProperty> scratch = new ArrayList<DataProperty>();
for (DataProperty p: props) {
if (p.getNamespace().equals(ontologyUri)) {
scratch.add(p);
}
}
props = scratch;
}
if (props != null) {
Collections.sort(props);
}
String json = new String();
int counter = 0;
if (props != null) {
if (props.size()==0) {
json = "{ \"name\": \"" + noResultsMsgStr + "\" }";
} else {
for (DataProperty prop: props) {
if ( counter > 0 ) {
json += ", ";
}
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? prop.getURI()==null ? "(no name)" : prop.getURI() : prop.getName() : prop.getPublicName();
try {
json += "{ \"name\": \"<a href='datapropEdit?uri="+URLEncoder.encode(prop.getURI(),"UTF-8")+"'>" + nameStr + "</a>\", ";
} catch (Exception e) {
json += "{ \"name\": \"" + nameStr + "\", ";
}
json += "\"data\": { \"internalName\": \"" + prop.getLocalNameWithPrefix() + "\", ";
/* VClass vc = null;
String domainStr="";
if (prop.getDomainClassURI() != null) {
vc = vcDao.getVClassByURI(prop.getDomainClassURI());
if (vc != null) {
try {
domainStr="<a href=\"vclassEdit?uri="+URLEncoder.encode(prop.getDomainClassURI(),"UTF-8")+"\">"+vc.getName()+"</a>";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
*/
VClass vc = (prop.getDomainClassURI() != null) ? vcDao.getVClassByURI(prop.getDomainClassURI()) : null;
String domainStr = (vc != null) ? vc.getLocalNameWithPrefix() : "";
json += "\"domainVClass\": \"" + domainStr + "\", " ;
Datatype rangeDatatype = dDao.getDatatypeByURI(prop.getRangeDatatypeURI());
String rangeDatatypeStr = (rangeDatatype==null)?prop.getRangeDatatypeURI():rangeDatatype.getName();
json += "\"rangeVClass\": \"" + rangeDatatypeStr + "\", " ;
if (prop.getGroupURI() != null) {
PropertyGroup pGroup = pgDao.getGroupByURI(prop.getGroupURI());
json += "\"group\": \"" + ((pGroup == null) ? "unknown group" : pGroup.getName()) + "\" } } " ;
} else {
json += "\"group\": \"unspecified\" } }" ;
}
counter += 1;
}
}
body.put("jsonTree",json);
}
} catch (Throwable t) {
t.printStackTrace();
}
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
}

View file

@ -0,0 +1,190 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
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.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class ListPropertyWebappsController extends FreemarkerHttpServlet {
private static Log log = LogFactory.getLog( ListPropertyWebappsController.class );
private static final String TEMPLATE_NAME = "siteAdmin-objectPropHierarchy.ftl";
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.EDIT_ONTOLOGY.ACTIONS;
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
try {
body.put("displayOption", "all");
body.put("pageTitle", "All Object Properties");
body.put("propertyType", "object");
String noResultsMsgStr = "No object properties found";
String ontologyUri = vreq.getParameter("ontologyUri");
ObjectPropertyDao dao = vreq.getFullWebappDaoFactory().getObjectPropertyDao();
PropertyInstanceDao piDao = vreq.getFullWebappDaoFactory().getPropertyInstanceDao();
VClassDao vcDao = vreq.getFullWebappDaoFactory().getVClassDao();
PropertyGroupDao pgDao = vreq.getFullWebappDaoFactory().getPropertyGroupDao();
String vclassURI = vreq.getParameter("vclassUri");
List props = new ArrayList();
if (vreq.getParameter("propsForClass") != null) {
noResultsMsgStr = "There are no object properties that apply to this class.";
// incomplete list of classes to check, but better than before
List<String> superclassURIs = vcDao.getAllSuperClassURIs(vclassURI);
superclassURIs.add(vclassURI);
superclassURIs.addAll(vcDao.getEquivalentClassURIs(vclassURI));
Map<String, PropertyInstance> propInstMap = new HashMap<String, PropertyInstance>();
for (String classURI : superclassURIs) {
Collection<PropertyInstance> propInsts = piDao.getAllPropInstByVClass(classURI);
for (PropertyInstance propInst : propInsts) {
propInstMap.put(propInst.getPropertyURI(), propInst);
}
}
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
propInsts.addAll(propInstMap.values());
Collections.sort(propInsts);
Iterator propInstIt = propInsts.iterator();
HashSet propURIs = new HashSet();
while (propInstIt.hasNext()) {
PropertyInstance pi = (PropertyInstance) propInstIt.next();
if (!(propURIs.contains(pi.getPropertyURI()))) {
propURIs.add(pi.getPropertyURI());
ObjectProperty prop = (ObjectProperty) dao.getObjectPropertyByURI(pi.getPropertyURI());
if (prop != null) {
props.add(prop);
}
}
}
} else {
props = (vreq.getParameter("iffRoot")!=null)
? dao.getRootObjectProperties()
: dao.getAllObjectProperties();
}
OntologyDao oDao = vreq.getFullWebappDaoFactory().getOntologyDao();
HashMap<String,String> ontologyHash = new HashMap<String,String>();
Iterator propIt = props.iterator();
List<ObjectProperty> scratch = new ArrayList();
while (propIt.hasNext()) {
ObjectProperty p = (ObjectProperty) propIt.next();
if (p.getNamespace()!=null) {
if( !ontologyHash.containsKey( p.getNamespace() )){
Ontology o = (Ontology)oDao.getOntologyByURI(p.getNamespace());
if (o==null) {
if (!VitroVocabulary.vitroURI.equals(p.getNamespace())) {
log.debug("doGet(): no ontology object found for the namespace "+p.getNamespace());
}
} else {
ontologyHash.put(p.getNamespace(), o.getName() == null ? p.getNamespace() : o.getName());
}
}
if (ontologyUri != null && p.getNamespace().equals(ontologyUri)) {
scratch.add(p);
}
}
}
if (ontologyUri != null) {
props = scratch;
}
if (props != null) {
Collections.sort(props, new ShowObjectPropertyHierarchyController.ObjectPropertyAlphaComparator());
}
String json = new String();
int counter = 0;
if (props != null) {
if (props.size()==0) {
json = "{ \"name\": \"" + noResultsMsgStr + "\" }";
} else {
Iterator propsIt = props.iterator();
while (propsIt.hasNext()) {
if ( counter > 0 ) {
json += ", ";
}
ObjectProperty prop = (ObjectProperty) propsIt.next();
String propNameStr = ShowObjectPropertyHierarchyController.getDisplayLabel(prop);
try {
json += "{ \"name\": \"<a href='./propertyEdit?uri="+URLEncoder.encode(prop.getURI(),"UTF-8")+"'>"
+ propNameStr + "</a>\", ";
} catch (Exception e) {
json += "{ \"name\": \"" + propNameStr + "\", ";
}
json += "\"data\": { \"internalName\": \"" + prop.getLocalNameWithPrefix() + "\", ";
VClass vc = (prop.getDomainVClassURI() != null) ? vcDao.getVClassByURI(prop.getDomainVClassURI()) : null;
String domainStr = (vc != null) ? vc.getLocalNameWithPrefix() : "";
json += "\"domainVClass\": \"" + domainStr + "\", " ;
vc = (prop.getRangeVClassURI() != null) ? vcDao.getVClassByURI(prop.getRangeVClassURI()) : null;
String rangeStr = (vc != null) ? vc.getLocalNameWithPrefix() : "";
json += "\"rangeVClass\": \"" + rangeStr + "\", " ;
if (prop.getGroupURI() != null) {
PropertyGroup pGroup = pgDao.getGroupByURI(prop.getGroupURI());
json += "\"group\": \"" + ((pGroup == null) ? "unknown group" : pGroup.getName()) + "\" } } " ;
} else {
json += "\"group\": \"unspecified\" } }" ;
}
counter += 1;
}
}
body.put("jsonTree",json);
}
} catch (Throwable t) {
t.printStackTrace();
}
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
}

View file

@ -11,7 +11,6 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -30,7 +29,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
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.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao;
@ -47,8 +45,6 @@ public class ShowClassHierarchyController extends FreemarkerHttpServlet {
private VClassDao vcDao = null;
private int previous_posn = 0;
private int childCount = 0;
private int uriCounter = 0;
@Override
protected Actions requiredActions(VitroRequest vreq) {
@ -116,7 +112,7 @@ public class ShowClassHierarchyController extends FreemarkerHttpServlet {
while (rootIt.hasNext()) {
VClass root = (VClass) rootIt.next();
if (root != null) {
json += addChildren(vreq.getFullWebappDaoFactory(), root, 0, ontologyUri,counter,"parent");
json += addChildren(vreq.getFullWebappDaoFactory(), root, 0, ontologyUri,counter);
counter += 1;
}
}
@ -134,7 +130,7 @@ public class ShowClassHierarchyController extends FreemarkerHttpServlet {
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
private String addChildren(WebappDaoFactory wadf, VClass parent, int position, String ontologyUri, int counter, String status) {
private String addChildren(WebappDaoFactory wadf, VClass parent, int position, String ontologyUri, int counter) {
String rowElts = addVClassDataToResultsList(wadf, parent, position, ontologyUri, counter);
int childShift = (rowElts.length() > 0) ? 1 : 0; // if addVClassDataToResultsList filtered out the result, don't shift the children over
int length = rowElts.length();
@ -157,7 +153,7 @@ public class ShowClassHierarchyController extends FreemarkerHttpServlet {
Iterator childClassIt = childClasses.iterator();
while (childClassIt.hasNext()) {
VClass child = (VClass) childClassIt.next();
leaves += addChildren(wadf, child, position + childShift, ontologyUri, counter, "child");
leaves += addChildren(wadf, child, position + childShift, ontologyUri, counter);
if (!childClassIt.hasNext()) {
if ( ontologyUri == null ) {
leaves += " }] ";
@ -166,15 +162,12 @@ public class ShowClassHierarchyController extends FreemarkerHttpServlet {
// need this for when we show the classes associated with an ontology
String ending = leaves.substring(leaves.length() - 2, leaves.length());
if ( ending.equals("] ") ) {
log.debug("[1] leaves += }]");
leaves += "}]";
}
else if ( ending.equals(" [") ){
log.debug("[2] leaves += ]");
leaves += "] ";
}
else {
log.debug("[3] leaves += }]");
leaves += "}]";
}
}

View file

@ -0,0 +1,251 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.net.URLEncoder;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.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.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.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
public class ShowDataPropertyHierarchyController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(ShowDataPropertyHierarchyController.class.getName());
private static final String TEMPLATE_NAME = "siteAdmin-objectPropHierarchy.ftl";
private int MAXDEPTH = 5;
private DataPropertyDao dpDao = null;
private VClassDao vcDao = null;
private PropertyGroupDao pgDao = null;
private DatatypeDao dDao = null;
private int previous_posn = 0;
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.EDIT_ONTOLOGY.ACTIONS;
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
try {
String displayOption = "";
if ( vreq.getParameter("displayOption") != null ) {
displayOption = vreq.getParameter("displayOption");
}
else {
displayOption = "hierarchy";
}
body.put("displayOption", displayOption);
if ( displayOption.equals("all") ) {
body.put("pageTitle", "All Data Properties");
}
else {
body.put("pageTitle", "Data Property Hierarchy");
}
body.put("propertyType", "data");
dpDao = vreq.getAssertionsWebappDaoFactory().getDataPropertyDao();
vcDao = vreq.getAssertionsWebappDaoFactory().getVClassDao();
pgDao = vreq.getAssertionsWebappDaoFactory().getPropertyGroupDao();
dDao = vreq.getAssertionsWebappDaoFactory().getDatatypeDao();
String json = new String();
String ontologyUri = vreq.getParameter("ontologyUri");
String startPropertyUri = vreq.getParameter("propertyUri");
List<DataProperty> roots = null;
if (startPropertyUri != null) {
roots = new LinkedList<DataProperty>();
roots.add(dpDao.getDataPropertyByURI(startPropertyUri));
} else {
roots = dpDao.getRootDataProperties();
if (roots!=null){
Collections.sort(roots);
}
}
int counter = 0;
if (roots!=null) {
Iterator<DataProperty> rootIt = roots.iterator();
if (!rootIt.hasNext()) {
DataProperty dp = new DataProperty();
dp.setURI(ontologyUri+"fake");
String notFoundMessage = "<strong>No data properties found.</strong>";
dp.setName(notFoundMessage);
dp.setName(notFoundMessage);
json += addDataPropertyDataToResultsList(dp, 0, ontologyUri, counter);
} else {
while (rootIt.hasNext()) {
DataProperty root = rootIt.next();
if ( (ontologyUri==null) || ( (ontologyUri!=null) && (root.getNamespace()!=null) && (ontologyUri.equals(root.getNamespace())) ) ) {
json += addChildren(root, 0, ontologyUri, counter);
counter += 1;
}
}
int length = json.length();
if ( length > 0 ) {
json += " }";
}
}
}
body.put("jsonTree",json);
} catch (Throwable t) {
t.printStackTrace();
}
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
private String addChildren(DataProperty parent, int position, String ontologyUri, int counter) {
if (parent == null) {
return "";
}
String details = addDataPropertyDataToResultsList(parent, position, ontologyUri, counter);
int length = details.length();
String leaves = "";
leaves += details;
List childURIstrs = dpDao.getSubPropertyURIs(parent.getURI());
if ((childURIstrs.size()>0) && position<MAXDEPTH) {
List childProps = new ArrayList();
Iterator childURIstrIt = childURIstrs.iterator();
while (childURIstrIt.hasNext()) {
String URIstr = (String) childURIstrIt.next();
DataProperty child = (DataProperty) dpDao.getDataPropertyByURI(URIstr);
childProps.add(child);
}
Collections.sort(childProps);
Iterator childPropIt = childProps.iterator();
while (childPropIt.hasNext()) {
DataProperty child = (DataProperty) childPropIt.next();
leaves += addChildren(child, position+1, ontologyUri, counter);
if (!childPropIt.hasNext()) {
if ( ontologyUri == null ) {
leaves += " }] ";
}
else if ( ontologyUri != null && length > 0 ) {
// need this for when we show the classes associated with an ontology
String ending = leaves.substring(leaves.length() - 2, leaves.length());
if ( ending.equals("] ") ) {
leaves += "}]";
}
else if ( ending.equals(" [") ){
leaves += "] ";
}
else {
leaves += "}]";
}
}
}
}
}
else {
if ( ontologyUri == null ) {
leaves += "] ";
}
else if ( ontologyUri != null && length > 0 ) {
leaves += "] ";
}
}
return leaves;
}
private String addDataPropertyDataToResultsList(DataProperty dp, int position, String ontologyUri, int counter) {
String tempString = "";
if (dp == null) {
return tempString;
}
if (ontologyUri == null || ( (dp.getNamespace()!=null) && (dp.getNamespace().equals(ontologyUri)) ) ) {
if ( counter < 1 && position < 1 ) {
tempString += "{ \"name\": ";
}
else if ( position == previous_posn ) {
tempString += "}, { \"name\": ";
}
else if ( position > previous_posn ) {
tempString += " { \"name\": ";
}
else if ( position < previous_posn ) {
tempString += "}, { \"name\": ";
}
String nameStr = dp.getPublicName()==null ? dp.getName()==null ? dp.getURI()==null ? "(no name)" : dp.getURI() : dp.getName() : dp.getPublicName();
try {
tempString += "\"<a href='datapropEdit?uri="+URLEncoder.encode(dp.getURI(),"UTF-8")+"'>" + nameStr + "</a>\", ";
} catch (Exception e) {
tempString += "\"" + nameStr + "\", ";
log.error("Unsupported: URLEncoder.encode() with UTF-8");
}
tempString += "\"data\": { \"internalName\": \"" + dp.getLocalNameWithPrefix() + "\", ";
VClass tmp = null;
try {
tempString += "\"domainVClass\": \"" + (((tmp = vcDao.getVClassByURI(dp.getDomainClassURI())) != null && (tmp.getLocalNameWithPrefix() == null)) ? "" : vcDao.getVClassByURI(dp.getDomainClassURI()).getLocalNameWithPrefix()) + "\", " ;
} catch (NullPointerException e) {
tempString += "\"domainVClass\": \"\",";
}
try {
Datatype rangeDatatype = dDao.getDatatypeByURI(dp.getRangeDatatypeURI());
String rangeDatatypeStr = (rangeDatatype==null)?dp.getRangeDatatypeURI():rangeDatatype.getName();
tempString += "\"rangeVClass\": \"" + ((rangeDatatypeStr != null) ? rangeDatatypeStr : "") + "\", " ;
} catch (NullPointerException e) {
tempString += "\"rangeVClass\": \"\",";
}
if (dp.getGroupURI() != null) {
PropertyGroup pGroup = pgDao.getGroupByURI(dp.getGroupURI());
tempString += "\"group\": \"" + ((pGroup == null) ? "unknown group" : pGroup.getName()) + "\" " ;
} else {
tempString += "\"group\": \"unspecified\"";
}
tempString += "}, \"children\": [";
previous_posn = position;
}
return tempString;
}
private class DataPropertyAlphaComparator implements Comparator {
public int compare(Object o1, Object o2) {
return Collator.getInstance().compare( ((DataProperty)o1).getName(), ((DataProperty)o2).getName());
}
}
}

View file

@ -0,0 +1,275 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.ObjectProperty;
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.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
public class ShowObjectPropertyHierarchyController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(ShowObjectPropertyHierarchyController.class.getName());
private static final String TEMPLATE_NAME = "siteAdmin-objectPropHierarchy.ftl";
private int MAXDEPTH = 5;
private ObjectPropertyDao opDao = null;
private VClassDao vcDao = null;
private PropertyGroupDao pgDao = null;
private int previous_posn = 0;
@Override
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.EDIT_ONTOLOGY.ACTIONS;
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
try {
String displayOption = "";
if ( vreq.getParameter("displayOption") != null ) {
displayOption = vreq.getParameter("displayOption");
}
else {
displayOption = "hierarchy";
}
body.put("displayOption", displayOption);
if ( displayOption.equals("all") ) {
body.put("pageTitle", "All Object Properties");
}
else {
body.put("pageTitle", "Object Property Hierarchy");
}
body.put("propertyType", "object");
opDao = vreq.getAssertionsWebappDaoFactory().getObjectPropertyDao();
vcDao = vreq.getAssertionsWebappDaoFactory().getVClassDao();
pgDao = vreq.getAssertionsWebappDaoFactory().getPropertyGroupDao();
String json = new String();
String ontologyUri = vreq.getParameter("ontologyUri");
String startPropertyUri = vreq.getParameter("propertyUri");
List<ObjectProperty> roots = null;
if (startPropertyUri != null) {
roots = new LinkedList<ObjectProperty>();
ObjectProperty op = opDao.getObjectPropertyByURI(startPropertyUri);
if (op == null) {
op = new ObjectProperty();
op.setURI(startPropertyUri);
}
roots.add(op);
} else {
roots = opDao.getRootObjectProperties();
if (roots!=null){
Collections.sort(roots, new ObjectPropertyAlphaComparator()); // sorts by domain public
}
}
int counter = 0;
if (roots != null) {
Iterator<ObjectProperty> rootIt = roots.iterator();
if (!rootIt.hasNext()) {
ObjectProperty op = new ObjectProperty();
op.setURI(ontologyUri+"fake");
String notFoundMessage = "<strong>No object properties found.</strong>";
op.setDomainPublic(notFoundMessage);
json += addObjectPropertyDataToResultsList(op, 0, ontologyUri, counter);
} else {
while (rootIt.hasNext()) {
ObjectProperty root = rootIt.next();
if ( (ontologyUri==null) ||
( (ontologyUri != null)
&& (root.getNamespace() != null)
&& (ontologyUri.equals(root.getNamespace())) ) ) {
json += addChildren(root, 0, ontologyUri, counter);
counter += 1;
}
}
int length = json.length();
if ( length > 0 ) {
json += " }";
}
}
}
body.put("jsonTree",json);
} catch (Throwable t) {
t.printStackTrace();
}
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
private String addChildren(ObjectProperty parent, int position, String ontologyUri, int counter) {
String details = addObjectPropertyDataToResultsList(parent, position, ontologyUri, counter);
int length = details.length();
String leaves = "";
leaves += details;
List childURIstrs = opDao.getSubPropertyURIs(parent.getURI());
if ((childURIstrs.size()>0) && position<MAXDEPTH) {
List childProps = new ArrayList();
Iterator childURIstrIt = childURIstrs.iterator();
while (childURIstrIt.hasNext()) {
String URIstr = (String) childURIstrIt.next();
ObjectProperty child = (ObjectProperty) opDao.getObjectPropertyByURI(URIstr);
childProps.add(child);
}
Collections.sort(childProps);
Iterator childPropIt = childProps.iterator();
while (childPropIt.hasNext()) {
ObjectProperty child = (ObjectProperty) childPropIt.next();
leaves += addChildren(child, position+1, ontologyUri, counter);
if (!childPropIt.hasNext()) {
if ( ontologyUri == null ) {
leaves += " }] ";
}
else if ( ontologyUri != null && length > 0 ) {
// need this for when we show the classes associated with an ontology
String ending = leaves.substring(leaves.length() - 2, leaves.length());
if ( ending.equals("] ") ) {
leaves += "}]";
}
else if ( ending.equals(" [") ){
leaves += "] ";
}
else {
leaves += "}]";
}
}
}
}
}
else {
if ( ontologyUri == null ) {
leaves += "] ";
}
else if ( ontologyUri != null && length > 0 ) {
leaves += "] ";
}
}
return leaves;
}
private String addObjectPropertyDataToResultsList(ObjectProperty op, int position, String ontologyUri, int counter) {
String tempString = "";
if (ontologyUri == null || ( (op.getNamespace()!=null) && (op.getNamespace().equals(ontologyUri)) ) ) {
// first if statement ensures that the first class begins with correct format
if ( counter < 1 && position < 1 ) {
tempString += "{ \"name\": ";
}
else if ( position == previous_posn ) {
tempString += "}, { \"name\": ";
}
else if ( position > previous_posn ) {
tempString += " { \"name\": ";
}
else if ( position < previous_posn ) {
tempString += "}, { \"name\": ";
}
try {
tempString += "\"<a href='propertyEdit?uri="+URLEncoder.encode(op.getURI(),"UTF-8") + "'>" + getDisplayLabel(op)+"</a>\", ";
} catch (UnsupportedEncodingException uee) {
tempString += "\"" + getDisplayLabel(op) + "\"";
log.error("Unsupported: URLEncoder.encode() with UTF-8");
}
tempString += "\"data\": { \"internalName\": \"" + op.getLocalNameWithPrefix() + "\", ";
VClass tmp = null;
try {
tempString += "\"domainVClass\": \"" + (((tmp = vcDao.getVClassByURI(op.getDomainVClassURI())) != null && (tmp.getLocalNameWithPrefix() == null)) ? "" : vcDao.getVClassByURI(op.getDomainVClassURI()).getLocalNameWithPrefix()) + "\", " ;
} catch (NullPointerException e) {
tempString += "\"domainVClass\": \"\",";
}
try {
tempString += "\"rangeVClass\": \"" + (((tmp = vcDao.getVClassByURI(op.getRangeVClassURI())) != null && (tmp.getLocalNameWithPrefix() == null)) ? "" : vcDao.getVClassByURI(op.getRangeVClassURI()).getLocalNameWithPrefix()) + "\", " ;
} catch (NullPointerException e) {
tempString += "\"rangeVClass\": \"\",";
}
if (op.getGroupURI() != null) {
PropertyGroup pGroup = pgDao.getGroupByURI(op.getGroupURI());
tempString += "\"group\": \"" + ((pGroup == null) ? "unknown group" : pGroup.getName()) + "\" " ;
} else {
tempString += "\"group\": \"unspecified\"";
}
tempString += "}, \"children\": [";
previous_posn = position;
}
return tempString;
}
public static class ObjectPropertyAlphaComparator implements Comparator<ObjectProperty> {
public int compare(ObjectProperty op1, ObjectProperty op2) {
if (op1 == null) {
return 1;
} else if (op2 == null) {
return -1;
}
String propLabel1 = getDisplayLabel(op1);
String propLabel2 = getDisplayLabel(op2);
if (propLabel1 == null) {
return 1;
} else if (propLabel2 == null) {
return -1;
} else {
return Collator.getInstance().compare( propLabel1, propLabel2 );
}
}
}
/*
* should never be null
*/
public static String getDisplayLabel(ObjectProperty op) {
String domainPublic = op.getDomainPublic();
String displayLabel = (domainPublic != null && domainPublic.length() > 0)
? domainPublic
: op.getLocalName();
return (displayLabel != null) ? displayLabel : "[object property]" ;
}
}

View file

@ -2,9 +2,15 @@
package edu.cornell.mannlib.vitro.webapp.controller.individual;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
@ -22,6 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.web.beanswrappers.ReadOnlyBeansWrapper;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
import edu.ucsf.vitro.opensocial.OpenSocialManager;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
@ -33,6 +40,9 @@ import freemarker.template.TemplateModelException;
* TODO clean this up.
*/
class IndividualResponseBuilder {
private static final Log log = LogFactory
.getLog(IndividualResponseBuilder.class);
private static final Map<String, String> namespaces = new HashMap<String, String>() {{
put("display", VitroVocabulary.DISPLAY);
put("vitro", VitroVocabulary.vitroURI);
@ -78,6 +88,24 @@ class IndividualResponseBuilder {
//If special values required for individuals like menu, include values in template values
body.putAll(getSpecialEditingValues());
// VIVO OpenSocial Extension by UCSF
try {
OpenSocialManager openSocialManager = new OpenSocialManager(vreq,
itm.isEditable() ? "individual-EDIT-MODE" : "individual", itm.isEditable());
openSocialManager.setPubsubData(OpenSocialManager.JSON_PERSONID_CHANNEL,
OpenSocialManager.buildJSONPersonIds(individual, "1 person found"));
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
if (openSocialManager.isVisible()) {
body.put("bodyOnload", "my.init();");
}
} catch (JSONException e) {
log.error("JSONException in doTemplate()", e);
} catch (IOException e) {
log.error("IOException in doTemplate()", e);
} catch (SQLException e) {
log.error("SQLException in doTemplate()", e);
}
String template = new IndividualTemplateLocator(vreq, individual).findTemplate();
return new TemplateResponseValues(template, body);

View file

@ -1,5 +1,5 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.dao;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
@ -34,9 +34,11 @@ public interface DataPropertyDao extends PropertyDao {
List<DataProperty> getRootDataProperties();
boolean annotateDataPropertyAsExternalIdentifier(String dataPropertyURI);
public List<DataProperty> getDataPropertyList(Individual subject);
boolean annotateDataPropertyAsExternalIdentifier(String dataPropertyURI);
public List<DataProperty> getDataPropertyList(Individual subject);
public List<DataProperty> getDataPropertyList(String subjectUri);
public String getCustomListViewConfigFileName(DataProperty dataProperty);
}

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import com.hp.hpl.jena.rdf.model.Literal;
@ -44,5 +45,9 @@ public interface DataPropertyStatementDao {
List<Literal> getDataPropertyValuesForIndividualByProperty(String subjectUri, String propertyUri);
List<Literal> getDataPropertyValuesForIndividualByProperty(Individual subject, DataProperty property, String queryString, Set<String> constructQueryStrings);
List<Literal> getDataPropertyValuesForIndividualByProperty(String subjectUri, String propertyUri, String queryString, Set<String> constructQueryStrings);
}

View file

@ -130,11 +130,14 @@ public class DisplayVocabulary {
public static final String HOME_MENU_ITEM = DISPLAY_NS + "HomeMenuItem";
/* some URIs of properties used with the SPARQL DataGetter */
/* some URIs of properties used with the SPARQL DataGetter, and save to var is saved for fixedHtml */
public static final String SAVE_TO_VAR = DISPLAY_NS + "saveToVar" ;
public static final String QUERY_MODEL = DISPLAY_NS + "queryModel";
public static final String QUERY = DISPLAY_NS + "query";
/* URI of property for Fixed HTML Generator */
public static final String FIXED_HTML_VALUE = DISPLAY_NS + "htmlValue";
//public static final Individual EVENTS = m_model.createIndividual( NS + "Events", PAGE );
//public static final Individual EVENTS_MENU_ITEM = m_model.createIndividual( NS + "EventsMenuItem", NAVIGATION_ELEMENT );

View file

@ -213,4 +213,9 @@ class DataPropertyDaoFiltering extends BaseFiltering implements DataPropertyDao{
return innerDataPropertyDao.getDataPropertyList(subjectUri);
}
@Override
public String getCustomListViewConfigFileName(DataProperty dataProperty) {
return innerDataPropertyDao.getCustomListViewConfigFileName(dataProperty);
}
}

View file

@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.hp.hpl.jena.rdf.model.Literal;
@ -18,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
class DataPropertyStatementDaoFiltering extends BaseFiltering implements DataPropertyStatementDao{
final DataPropertyStatementDao innerDataPropertyStatementDao;
final VitroFilters filters;
@ -141,4 +143,48 @@ class DataPropertyStatementDaoFiltering extends BaseFiltering implements DataPro
}
@Override
public List<Literal> getDataPropertyValuesForIndividualByProperty(Individual subject, DataProperty property, String queryString, Set<String> constructQueryStrings) {
return getDataPropertyValuesForIndividualByProperty(subject.getURI(), property.getURI(), queryString, constructQueryStrings);
}
@Override
public List<Literal> getDataPropertyValuesForIndividualByProperty(String subjectUri, String propertyUri, String queryString, Set<String> constructQueryStrings) {
List<Literal> literals = innerDataPropertyStatementDao.getDataPropertyValuesForIndividualByProperty(subjectUri, propertyUri, queryString, constructQueryStrings);
/* Filter the data
*
* Filtering is applied to a list of DataPropertyStatement. Create these statements, mapped
* to the literal that they are built from, apply filtering to the statements, then get
* the associated literals out of the original list. Use a LinkedHashMap to preserve the ordering.
*/
Map<DataPropertyStatement, Literal> stmtsToLiterals =
new LinkedHashMap<DataPropertyStatement, Literal>(literals.size());
for (Literal literal : literals) {
String value = literal.getLexicalForm();
DataPropertyStatement statement = new DataPropertyStatementImpl(subjectUri, propertyUri, value);
statement.setDatatypeURI(literal.getDatatypeURI());
statement.setLanguage(literal.getLanguage());
stmtsToLiterals.put(statement, literal);
}
List<DataPropertyStatement> stmtList = new ArrayList<DataPropertyStatement>(stmtsToLiterals.keySet());
// Apply the filters to the list of statements
List<DataPropertyStatement> filteredStatements = filter(stmtList, filters.getDataPropertyStatementFilter());
// Get the literals associated with the filtered statements out of the original list
List<Literal> filteredLiterals = new ArrayList<Literal>(filteredStatements.size());
for (DataPropertyStatement dps : filteredStatements) {
if (dps instanceof DataPropertyStatementFiltering) {
dps = ((DataPropertyStatementFiltering)dps).innerStmt;
}
filteredLiterals.add(stmtsToLiterals.get(dps));
}
// Return the filtered list of literals
return filteredLiterals;
}
}

View file

@ -11,6 +11,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@ -25,6 +26,8 @@ import com.hp.hpl.jena.ontology.ProfileException;
import com.hp.hpl.jena.ontology.Restriction;
import com.hp.hpl.jena.ontology.SomeValuesFromRestriction;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
@ -729,5 +732,52 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
return properties;
}
protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING =
"PREFIX display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#>" +
"SELECT ?property ?filename WHERE { \n" +
" ?property display:listViewConfigFile ?filename . \n" +
"}";
protected static Query listViewConfigFileQuery = null;
static {
try {
listViewConfigFileQuery = QueryFactory.create(LIST_VIEW_CONFIG_FILE_QUERY_STRING);
} catch(Throwable th){
log.error("could not create SPARQL query for LIST_VIEW_CONFIG_FILE_QUERY_STRING " + th.getMessage());
log.error(LIST_VIEW_CONFIG_FILE_QUERY_STRING);
}
}
Map<DataProperty, String> customListViewConfigFileMap = null;
@Override
public String getCustomListViewConfigFileName(DataProperty dp) {
if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<DataProperty, String>();
OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
ResultSet results = qexec.execSelect();
//Iterate through mappings looking for the current property and setting up a hashmap for subsequent retrieval
while (results.hasNext()) {
QuerySolution soln = results.next();
String propertyUri = soln.getResource("property").getURI();
DataProperty prop = getDataPropertyByURI(propertyUri);
if (prop == null) {
//This is a warning only if this property is the one for which we're searching
if(dp.getURI().equals(propertyUri)){
log.warn("Can't find property for uri " + propertyUri);
} else {
log.debug("Can't find property for uri " + propertyUri);
}
} else {
String filename = soln.getLiteral("filename").getLexicalForm();
customListViewConfigFileMap.put(prop, filename);
}
}
qexec.close();
}
return customListViewConfigFileMap.get(dp);
}
}

View file

@ -8,6 +8,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.hp.hpl.jena.datatypes.TypeMapper;
import com.hp.hpl.jena.ontology.OntModel;
@ -18,10 +19,15 @@ import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
@ -38,6 +44,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ObjectPropertyStatementDaoJena;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -190,6 +197,7 @@ public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPro
Resource res = ResourceFactory.createResource(entity.getURI());
if (!VitroVocabulary.PSEUDO_BNODE_NS.equals(entity.getNamespace())) {
for (Literal lit : this.getDataPropertyValuesForIndividualByProperty(res.getURI(), datapropURI)) {
log.debug("Literal lit = " + lit);
DataPropertyStatement ed = new DataPropertyStatementImpl();
fillDataPropertyStatementWithJenaLiteral(ed, lit);
ed.setIndividualURI(entity.getURI());
@ -390,4 +398,126 @@ public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPro
}
}
@Override
public List<Literal> getDataPropertyValuesForIndividualByProperty(
Individual subject,
DataProperty property,
String queryString, Set<String> constructQueryStrings ) {
return getDataPropertyValuesForIndividualByProperty(subject.getURI(), property.getURI(), queryString, constructQueryStrings );
}
@Override
public List<Literal> getDataPropertyValuesForIndividualByProperty(
String subjectUri,
String propertyUri,
String queryString, Set<String> constructQueryStrings ) {
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings);
log.debug("Query string for data property " + propertyUri + ": " + queryString);
Query query = null;
try {
query = QueryFactory.create(queryString, Syntax.syntaxARQ);
} catch(Throwable th){
log.error("Could not create SPARQL query for query string. " + th.getMessage());
log.error(queryString);
return Collections.emptyList();
}
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
initialBindings.add("property", ResourceFactory.createResource(propertyUri));
// Run the SPARQL query to get the properties
List<Literal> values = new ArrayList<Literal>();
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
QueryExecution qexec = null;
try {
qexec = (constructedModel == null)
? QueryExecutionFactory.create(
query, dataset, initialBindings)
: QueryExecutionFactory.create(
query, constructedModel, initialBindings);
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution sol = results.next();
Literal value = sol.getLiteral("value");
values.add(value);
}
log.debug("values = " + values);
return values;
} catch (Exception e) {
log.error("Error getting data property values for subject " + subjectUri + " and property " + propertyUri);
return Collections.emptyList();
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
if (qexec != null) {
qexec.close();
}
}
}
private Model constructModelForSelectQueries(String subjectUri,
String propertyUri,
Set<String> constructQueries) {
if (constructQueries == null) {
return null;
}
Model constructedModel = ModelFactory.createDefaultModel();
for (String queryString : constructQueries) {
log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
Query query = null;
try {
query = QueryFactory.create(queryString, Syntax.syntaxARQ);
} catch(Throwable th){
log.error("Could not create CONSTRUCT SPARQL query for query " +
"string. " + th.getMessage());
log.error(queryString);
return constructedModel;
}
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add(
"subject", ResourceFactory.createResource(subjectUri));
initialBindings.add(
"property", ResourceFactory.createResource(propertyUri));
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
QueryExecution qe = null;
try {
qe = QueryExecutionFactory.create(
query, dataset, initialBindings);
qe.execConstruct(constructedModel);
} catch (Exception e) {
log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri);
} finally {
if (qe != null) {
qe.close();
}
dataset.getLock().leaveCriticalSection();
w.close();
}
}
return constructedModel;
}
}

View file

@ -1,6 +1,5 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
@ -49,8 +48,6 @@ public class RDFServiceGraph implements GraphWithPerform {
private PrefixMapping prefixMapping = new PrefixMappingImpl();
private GraphEventManager eventManager;
private Reifier reifier = new EmptyReifier(this);
private GraphStatisticsHandler graphStatisticsHandler;
private TransactionHandler transactionHandler;
private QueryHandler queryHandler;
/**
@ -83,26 +80,6 @@ public class RDFServiceGraph implements GraphWithPerform {
public void add(Triple arg0) throws AddDeniedException {
performAdd(arg0);
}
// public void executeUpdate(String updateString) {
// try {
// RepositoryConnection conn = getConnection();
// try {
// Update u = conn.prepareUpdate(QueryLanguage.SPARQL, updateString);
// u.execute();
// } catch (MalformedQueryException e) {
// throw new RuntimeException(e);
// } catch (UpdateExecutionException e) {
// log.error(e,e);
// log.error("Update command: \n" + updateString);
// throw new RuntimeException(e);
// } finally {
// conn.close();
// }
// } catch (RepositoryException re) {
// throw new RuntimeException(re);
// }
// }
private String serialize(Triple t) {
StringBuffer sb = new StringBuffer();
@ -130,8 +107,8 @@ public class RDFServiceGraph implements GraphWithPerform {
public void performDelete(Triple t) {
ChangeSet changeSet = rdfService.manufactureChangeSet();
try {
changeSet.addRemoval(new ByteArrayInputStream(
serialize(t).getBytes()), RDFService.ModelSerializationFormat.N3, graphURI);
changeSet.addRemoval(RDFServiceUtils.toInputStream(serialize(t)),
RDFService.ModelSerializationFormat.N3, graphURI);
rdfService.changeSetUpdate(changeSet);
} catch (RDFServiceException rdfse) {
throw new RuntimeException(rdfse);
@ -268,16 +245,8 @@ public class RDFServiceGraph implements GraphWithPerform {
findQuery.append("\n}");
String queryString = findQuery.toString();
//log.info(queryString);
// //TODO remove me
// if (queryString.contains("individual/AI") && queryString.contains("label")) {
// throw new RuntimeException("break!");
// }
ResultSet rs = execSelect(queryString);
//rs = execSelect(findQuery.toString());
//rs = execSelect(findQuery.toString());
List<Triple> triplist = new ArrayList<Triple>();
while (rs.hasNext()) {
@ -324,9 +293,6 @@ public class RDFServiceGraph implements GraphWithPerform {
@Override
public Reifier getReifier() {
//if (reifier == null) {
// reifier = new SimpleReifier(this, ReificationStyle.Standard);
//}
return reifier;
}
@ -354,7 +320,6 @@ public class RDFServiceGraph implements GraphWithPerform {
@Override
public boolean isIsomorphicWith(Graph arg0) {
log.info("Hey dummy!");
throw new UnsupportedOperationException("isIsomorphicWith() not supported " +
"by SPARQL graphs");
}

View file

@ -73,7 +73,6 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
@Override
public void add(Graph g, boolean arg1) {
log.info("bulk addGraph()");
Model[] model = separateStatementsWithBlankNodes(g);
addModel(model[1] /* nonBlankNodeModel */);
// replace following call with different method
@ -118,7 +117,6 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
}
public void addModel(Model model) {
log.info("bulk addModel()");
ChangeSet changeSet = graph.getRDFService().manufactureChangeSet();
ByteArrayOutputStream out = new ByteArrayOutputStream();
model.write(out, "N-TRIPLE");
@ -133,7 +131,6 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
}
public void deleteModel(Model model) {
log.info("bulk addModel()");
ChangeSet changeSet = graph.getRDFService().manufactureChangeSet();
ByteArrayOutputStream out = new ByteArrayOutputStream();
model.write(out, "N-TRIPLE");
@ -180,22 +177,7 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
public static void removeAll( Graph g )
{
ExtendedIterator<Triple> it = GraphUtil.findAll(g);
try {
while (it.hasNext()) {
Triple t = it.next();
g.delete(t);
it.remove();
}
} finally {
it.close();
}
// get rid of remaining blank nodes using a SPARQL DELETE
if (g instanceof SparqlGraph) {
((SparqlGraph) g).removeAll();
}
g.getBulkUpdateHandler().delete(g);
}
}

View file

@ -13,6 +13,7 @@ import javax.servlet.http.HttpSession;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
@ -154,7 +155,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen
//For the case of a new page
if(subjectUri == null) {
//Once added, return to pageList
editConfiguration.setUrlToReturnTo("/pageList");
editConfiguration.setUrlToReturnTo(UrlBuilder.getUrl("/pageList"));
editConfiguration.setEntityToReturnTo("?page");
editConfiguration.setPredicateUri(predicateUri);
@ -190,8 +191,10 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen
//In the case where this is a new page, need to ensure page gets a new
private void setNewResources(EditConfigurationVTwo conf) {
//null makes default namespace be triggered
conf.addNewResource("page", defaultDisplayNs);
conf.addNewResource("menuItem", defaultDisplayNs);
//conf.addNewResource("page", defaultDisplayNs);
//conf.addNewResource("menuItem", defaultDisplayNs);
conf.addNewResource("page", null);
conf.addNewResource("menuItem", null);
}

View file

@ -25,9 +25,11 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.ManagePageGenerator;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3Utils;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.util.JSONUtils;
public class ManagePagePreprocessor extends
BaseEditSubmissionPreprocessorVTwo {
@ -83,7 +85,7 @@ public class ManagePagePreprocessor extends
int counter = 0;
for(JSONObject jsonObject:pageContentUnitsJSON) {
String dataGetterClass = getDataGetterClass(jsonObject);
ProcessDataGetterN3 pn = ProcessDataGetterN3Utils.getDataGetterProcessorN3(dataGetterClass);
ProcessDataGetterN3 pn = ProcessDataGetterN3Utils.getDataGetterProcessorN3(dataGetterClass, jsonObject);
//Add n3 required
addN3Required(pn, counter);
//Add N3 Optional as well
@ -106,7 +108,13 @@ public class ManagePagePreprocessor extends
// TODO Auto-generated method stub
List<String> newResources = pn.getNewResources(counter);
for(String newResource:newResources) {
editConfiguration.addNewResource(newResource, ManagePageGenerator.defaultDisplayNs);
//Will null get us display vocabulary or something else?
editConfiguration.addNewResource(newResource, null);
//Weirdly enough, the defaultDisplayNS doesn't act as a namespace REALLY
//as it first gets assigned as the URI itself and this lead to an error
//instead of repetitively trying to get another URI
//editConfiguration.addNewResource(newResource, ManagePageGenerator.defaultDisplayNs );
}
}
@ -130,23 +138,51 @@ public class ManagePagePreprocessor extends
List<String> uriLabels = pn.getUriVarNamesBase();
for(String literalLabel:literalLabels) {
//TODO: Deal with multiple submission values
//This retrieves the value for this particular json object
String literalValue = jsonObject.getString(literalLabel);
//Var names will depend on which data getter object this is on the page, so depends on counter
List<String> literalValues = new ArrayList<String>();
Object jsonValue = jsonObject.get(literalLabel);
//Var names will depend on which data getter object this is on the page, so depends on counter
String submissionLiteralName = pn.getVarName(literalLabel, counter);
//Single value
if(jsonValue instanceof String) {
//TODO: Deal with multiple submission values
//This retrieves the value for this particular json object
literalValues.add(jsonObject.getString(literalLabel));
} else if(jsonValue instanceof JSONArray) {
JSONArray values = jsonObject.getJSONArray(literalLabel);
literalValues = (List<String>) JSONSerializer.toJava(values);
}
String[] literalValuesSubmission = new String[literalValues.size()];
literalValuesSubmission = literalValues.toArray(literalValuesSubmission);
//This adds literal, connecting the field with
submission.addLiteralToForm(editConfiguration, editConfiguration.getField(submissionLiteralName), submissionLiteralName, new String[]{literalValue});
submission.addLiteralToForm(editConfiguration,
editConfiguration.getField(submissionLiteralName),
submissionLiteralName,
literalValuesSubmission);
}
for(String uriLabel:uriLabels) {
//TODO: Deal with multiple submission values
//This retrieves the value for this particular json object
String uriValue = jsonObject.getString(uriLabel);
//Var names will depend on which data getter object this is on the page, so depends on counter
List<String> uriValues = new ArrayList<String>();
Object jsonValue = jsonObject.get(uriLabel);
//Var names will depend on which data getter object this is on the page, so depends on counter
String submissionUriName = pn.getVarName(uriLabel, counter);
//This adds literal, connecting the field with
submission.addLiteralToForm(editConfiguration, editConfiguration.getField(submissionUriName), submissionUriName, new String[]{uriValue});
//if single value, then, add to values
if(jsonValue instanceof String) {
//Var names will depend on which data getter object this is on the page, so depends on counter
//This retrieves the value for this particular json object and adds to list
uriValues.add(jsonObject.getString(uriLabel));
} else if(jsonValue instanceof JSONArray) {
//multiple values
JSONArray values = jsonObject.getJSONArray(uriLabel);
uriValues = (List<String>) JSONSerializer.toJava(values);
} else {
//This may include JSON Objects but no way to deal with these right now
}
String[] uriValuesSubmission = new String[uriValues.size()];
uriValuesSubmission = uriValues.toArray(uriValuesSubmission);
//This adds literal, connecting the field with the value
submission.addUriToForm(editConfiguration, submissionUriName, uriValuesSubmission);
}
//this needs to be different

View file

@ -0,0 +1,95 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
//Returns the appropriate n3 based on data getter
public class ProcessClassGroupDataGetterN3 extends ProcessDataGetterAbstract {
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData";
private static String classGroupVarBase = "classGroup";
public ProcessClassGroupDataGetterN3(){
}
//Pass in variable that represents the counter
//TODO: ensure correct model returned
//We shouldn't use the ACTUAL values here but generate the n3 required
public List<String> retrieveN3Required(int counter) {
return this.retrieveN3ForTypeAndClassGroup(counter);
}
public List<String> retrieveN3Optional(int counter) {
return null;
}
public List<String> retrieveN3ForTypeAndClassGroup(int counter) {
String n3ForType = this.getN3ForTypePartial(counter);
String n3 = n3ForType +"; \n" +
"<" + DisplayVocabulary.FOR_CLASSGROUP + "> " + getN3VarName(classGroupVarBase, counter) + " .";
List<String> n3List = new ArrayList<String>();
n3List.add(getPrefixes() + n3);
return n3List;
}
public String getN3ForTypePartial(int counter) {
String dataGetterVar = getDataGetterVar(counter);
String n3 = dataGetterVar + " a <" + getClassType() + ">";
return n3;
}
//These methods will return the literals and uris expected within the n3
//and the counter is used to ensure they are numbered correctly
public List<String> retrieveLiteralsOnForm(int counter) {
//no literals, just the class group URI
List<String> literalsOnForm = new ArrayList<String>();
return literalsOnForm;
}
public List<String> retrieveUrisOnForm(int counter) {
List<String> urisOnForm = new ArrayList<String>();
//Class group is a URI
urisOnForm.add(getVarName("classGroup", counter));
return urisOnForm;
}
public List<FieldVTwo> retrieveFields(int counter) {
List<FieldVTwo> fields = new ArrayList<FieldVTwo>();
fields.add(new FieldVTwo().setName(getVarName("classGroup", counter)));
return fields;
}
//These var names match the names of the elements within the json object returned with the info required for the data getter
public List<String> getLiteralVarNamesBase() {
return Arrays.asList();
}
//these are for the fields ON the form
public List<String> getUriVarNamesBase() {
return Arrays.asList("classGroup");
}
//This class can be extended so returning type here
public String getClassType() {
return classType;
}
}

View file

@ -0,0 +1,53 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
//Returns the appropriate n3 based on data getter
public abstract class ProcessDataGetterAbstract implements ProcessDataGetterN3 {
public ProcessDataGetterAbstract(){
}
//placeholder so need "?" in front of the variable
public String getDataGetterVar(int counter) {
return "?dataGetter" + counter;
}
public String getPrefixes() {
return "@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> . \n" +
"@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> . \n";
}
public String getVarName(String base, int counter) {
return base + counter;
}
//For use within n3 strings, need a "?"
public String getN3VarName(String base, int counter) {
return "?" + getVarName(base, counter);
}
//Return name of new resources
public List<String> getNewResources(int counter) {
//Each data getter requires a new resource
List<String> newResources = new ArrayList<String>();
newResources.add("dataGetter" + counter);
return newResources;
}
}

View file

@ -10,7 +10,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
//Returns the appropriate n3 based on data getter
public interface ProcessDataGetterN3 {
public List<String> retrieveN3Required(int counter);
public List<String> retrieveN3Required(int counter);
public List<String> retrieveN3Optional(int counter);
public List<String >retrieveLiteralsOnForm(int counter);

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
@ -20,6 +21,7 @@ import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
/*
* This class determines what n3 should be returned for a particular data getter and can be overwritten or extended in VIVO.
@ -29,18 +31,20 @@ public class ProcessDataGetterN3Utils {
public static HashMap<String, String> getDataGetterTypeToProcessorMap() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessSparqlDataGetterN3");
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessClassGroupDataGetterN3");
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessIndividualsForClassesDataGetterN3");
map.put("edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter", "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessFixedHTMLN3");
return map;
}
public static ProcessDataGetterN3 getDataGetterProcessorN3(String dataGetterClass) {
public static ProcessDataGetterN3 getDataGetterProcessorN3(String dataGetterClass, JSONObject jsonObject) {
HashMap<String, String> map = getDataGetterTypeToProcessorMap();
//
if(map.containsKey(dataGetterClass)) {
String processorClass = map.get(dataGetterClass);
try {
Class<?> clz = Class.forName(processorClass);
//Don't actually need to pass in json object since that includes the actual submission values
ProcessDataGetterN3 pn = (ProcessDataGetterN3) clz.getConstructor().newInstance();
ProcessDataGetterN3 pn = instantiateClass(processorClass, jsonObject);
return pn;
} catch(Exception ex) {
log.error("Exception occurred in trying to get processor class for n3 for " + dataGetterClass, ex);
@ -50,4 +54,25 @@ public class ProcessDataGetterN3Utils {
return null;
}
private static ProcessDataGetterN3 instantiateClass(String processorClass, JSONObject jsonObject) {
ProcessDataGetterN3 pn = null;
try {
Class<?> clz = Class.forName(processorClass);
Constructor<?>[] ctList = clz.getConstructors();
for (Constructor<?> ct: ctList) {
Class<?>[] parameterTypes =ct.getParameterTypes();
if(parameterTypes.length > 0 && parameterTypes[0].isAssignableFrom(jsonObject.getClass())) {
pn = (ProcessDataGetterN3) ct.newInstance(jsonObject);
} else {
pn = (ProcessDataGetterN3) ct.newInstance();
}
}
} catch(Exception ex) {
log.error("Error occurred instantiating " + processorClass, ex);
}
return pn;
}
}

View file

@ -0,0 +1,81 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
//Returns the appropriate n3 based on data getter
public class ProcessFixedHTMLN3 extends ProcessDataGetterAbstract {
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter";
public ProcessFixedHTMLN3(){
}
//Pass in variable that represents the counter
//TODO: ensure correct model returned
//We shouldn't use the ACTUAL values here but generate the n3 required
public List<String> retrieveN3Required(int counter) {
String dataGetterVar = getDataGetterVar(counter);
String n3 = dataGetterVar + " a <" + classType + ">; \n" +
"display:saveToVar " + getN3VarName("saveToVar", counter) + "; \n" +
"display:htmlValue " + getN3VarName("htmlValue", counter) + " .";
List<String> requiredList = new ArrayList<String>();
requiredList.add(getPrefixes() + n3);
return requiredList;
}
public List<String> retrieveN3Optional(int counter) {
return null;
}
public List<String> retrieveLiteralsOnForm(int counter) {
List<String> literalsOnForm = new ArrayList<String>();
literalsOnForm.add(getVarName("saveToVar",counter));
literalsOnForm.add(getVarName("htmlValue", counter));
return literalsOnForm;
}
public List<String> retrieveUrisOnForm(int counter) {
List<String> urisOnForm = new ArrayList<String>();
return urisOnForm;
}
public List<FieldVTwo> retrieveFields(int counter) {
List<FieldVTwo> fields = new ArrayList<FieldVTwo>();
//fields.add(new FieldVTwo().setName(getVarName("dataGetter", counter)));
fields.add(new FieldVTwo().setName(getVarName("saveToVar", counter)));
fields.add(new FieldVTwo().setName(getVarName("htmlValue", counter)));
return fields;
}
public List<String> getLiteralVarNamesBase() {
return Arrays.asList("saveToVar", "htmlValue");
}
//these are for the fields ON the form
public List<String> getUriVarNamesBase() {
return Arrays.asList();
}
}

View file

@ -0,0 +1,139 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
//Returns the appropriate n3 for selection of classes from within class group
public class ProcessIndividualsForClassesDataGetterN3 extends ProcessClassGroupDataGetterN3 {
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter";
protected JSONObject values = null;
int classCount = 0;
protected static String individualClassVarNameBase = "classesSelectedInClassGroup";
public ProcessIndividualsForClassesDataGetterN3(JSONObject jsonObject){
this.values = jsonObject;
if(values != null && values.containsKey(individualClassVarNameBase)) {
//Check how many individual classes are in json object
JSONArray ja = values.getJSONArray(individualClassVarNameBase);
classCount = ja.size();
}
}
//Pass in variable that represents the counter
//TODO: ensure correct model returned
//We shouldn't use the ACTUAL values here but generate the n3 required
public List<String> retrieveN3Required(int counter) {
List<String> classGroupN3 = this.retrieveN3ForTypeAndClassGroup(counter);
classGroupN3.addAll(this.addIndividualClassesN3(counter));
return classGroupN3;
}
protected List<String> addIndividualClassesN3(int counter) {
List<String> classN3 = new ArrayList<String>();
if(classCount > 0) {
classN3.add(generateIndividualClassN3(counter));
}
return classN3;
}
protected String generateIndividualClassN3(int counter) {
String dataGetterVar = getDataGetterVar(counter);
String n3 = dataGetterVar + " <" + DisplayVocabulary.GETINDIVIDUALS_FOR_CLASS + "> ";
//Consider a multi-valued field - in this case single field with multiple values
n3 += getN3VarName(individualClassVarNameBase, counter);
/*
int i;
for(i = 0; i < classCount; i++) {
if(i != 0) {
n3+= ",";
}
n3 += getN3VarName(individualClassVarNameBase + counter, classCount);
}*/
n3 += " .";
return n3;
}
public List<String> retrieveN3Optional(int counter) {
return null;
}
//These methods will return the literals and uris expected within the n3
//and the counter is used to ensure they are numbered correctly
public List<String> retrieveLiteralsOnForm(int counter) {
//no literals, just the class group URI
List<String> literalsOnForm = new ArrayList<String>();
return literalsOnForm;
}
public List<String> retrieveUrisOnForm(int counter) {
//get class group uris
List<String> urisOnForm = super.retrieveUrisOnForm(counter);
//now get individual classes selected uri
//urisOnForm.addAll(getIndividualClassesVarNames(counter));
//here again,consider multi-valued
urisOnForm.add(getVarName(individualClassVarNameBase, counter));
return urisOnForm;
}
private List<String> getIndividualClassesVarNames(int counter) {
List<String> individualClassUris = new ArrayList<String>();
int i;
for(i = 0; i < classCount; i++) {
individualClassUris.add(getVarName(individualClassVarNameBase + counter, classCount));
}
return individualClassUris;
}
public List<FieldVTwo> retrieveFields(int counter) {
List<FieldVTwo> fields = super.retrieveFields(counter);
fields.add(new FieldVTwo().setName(getVarName(individualClassVarNameBase, counter)));
//Add fields for each class selected
/* List<String> classVarNames = getIndividualClassesVarNames(counter);
for(String v:classVarNames) {
fields.add(new FieldVTwo().setName(v));
}*/
return fields;
}
//These var names match the names of the elements within the json object returned with the info required for the data getter
public List<String> getLiteralVarNamesBase() {
return Arrays.asList();
}
//these are for the fields ON the form
public List<String> getUriVarNamesBase() {
return Arrays.asList("classGroup", individualClassVarNameBase);
}
@Override
public String getClassType() {
return classType;
}
}

View file

@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
//Returns the appropriate n3 based on data getter
public class ProcessSparqlDataGetterN3 implements ProcessDataGetterN3 {
public class ProcessSparqlDataGetterN3 extends ProcessDataGetterAbstract {
private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter";
public ProcessSparqlDataGetterN3(){
@ -39,15 +39,6 @@ public class ProcessSparqlDataGetterN3 implements ProcessDataGetterN3 {
public List<String> retrieveN3Optional(int counter) {
return null;
}
//placeholder so need "?" in front of the variable
public String getDataGetterVar(int counter) {
return "?dataGetter" + counter;
}
private String getPrefixes() {
return "@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> . \n" +
"@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> . \n";
}
//Need to add method sfor returning the fields, literals on form, and all that
@ -105,22 +96,7 @@ public class ProcessSparqlDataGetterN3 implements ProcessDataGetterN3 {
return Arrays.asList("queryModel");
}
public String getVarName(String base, int counter) {
return base + counter;
}
//For use within n3 strings, need a "?"
public String getN3VarName(String base, int counter) {
return "?" + getVarName(base, counter);
}
//Return name of new resources
public List<String> getNewResources(int counter) {
//Each data getter requires a new resource
List<String> newResources = new ArrayList<String>();
newResources.add("dataGetter" + counter);
return newResources;
}
}

View file

@ -13,16 +13,21 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.query.DataSource;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.DatasetFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.listeners.StatementListener;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.sdb.SDBFactory;
@ -30,11 +35,6 @@ 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.shared.Lock;
import com.hp.hpl.jena.update.GraphStore;
import com.hp.hpl.jena.update.GraphStoreFactory;
import com.hp.hpl.jena.update.UpdateAction;
import com.hp.hpl.jena.update.UpdateFactory;
import com.hp.hpl.jena.update.UpdateRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph;
@ -141,6 +141,7 @@ public class RDFServiceSDB extends RDFServiceImpl implements RDFService {
}
private void removeBlankNodesWithSparqlUpdate(Dataset dataset, Model model, String graphURI) {
Model blankNodeModel = ModelFactory.createDefaultModel();
StmtIterator stmtIt = model.listStatements();
while (stmtIt.hasNext()) {
@ -149,7 +150,61 @@ public class RDFServiceSDB extends RDFServiceImpl implements RDFService {
blankNodeModel.add(stmt);
}
}
removeUsingSparqlUpdate(dataset, blankNodeModel, graphURI);
String rootFinder = "SELECT ?s WHERE { ?s ?p ?o OPTIONAL { ?ss ?pp ?s } FILTER (!bound(?ss)) }";
Query rootFinderQuery = QueryFactory.create(rootFinder);
QueryExecution qe = QueryExecutionFactory.create(rootFinderQuery, blankNodeModel);
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
QuerySolution qs = rs.next();
Resource s = qs.getResource("s");
String treeFinder = makeDescribe(s);
Query treeFinderQuery = QueryFactory.create(treeFinder);
QueryExecution qee = QueryExecutionFactory.create(treeFinderQuery, blankNodeModel);
try {
Model tree = qee.execDescribe();
StmtIterator sit = tree.listStatements(s, null, (RDFNode) null);
while (sit.hasNext()) {
Statement stmt = sit.nextStatement();
RDFNode n = stmt.getObject();
Model m2 = ModelFactory.createDefaultModel();
if (n.isResource()) {
Resource s2 = (Resource) n;
// now run yet another describe query
String smallerTree = makeDescribe(s2);
Query smallerTreeQuery = QueryFactory.create(smallerTree);
QueryExecution qe3 = QueryExecutionFactory.create(
smallerTreeQuery, tree);
try {
qe3.execDescribe(m2);
} finally {
qe3.close();
}
}
m2.add(stmt);
DataSource ds = DatasetFactory.create();
ds.addNamedModel(graphURI, dataset.getNamedModel(graphURI));
removeUsingSparqlUpdate(ds, m2, graphURI);
}
} finally {
qee.close();
}
}
} finally {
qe.close();
}
}
private String makeDescribe(Resource s) {
StringBuffer query = new StringBuffer("DESCRIBE <") ;
if (s.isAnon()) {
query.append("_:" + s.getId().toString());
} else {
query.append(s.getURI());
}
query.append(">");
return query.toString();
}
private void removeUsingSparqlUpdate(Dataset dataset, Model model, String graphURI) {
@ -173,11 +228,8 @@ public class RDFServiceSDB extends RDFServiceImpl implements RDFService {
}
StringBuffer queryBuff = new StringBuffer();
queryBuff.append("DELETE { " + ((graphURI != null) ? "GRAPH <" + graphURI + "> { " : "" ) + " \n");
queryBuff.append("CONSTRUCT { \n");
queryBuff.append(patternBuff);
if (graphURI != null) {
queryBuff.append(" } \n");
}
queryBuff.append("} WHERE { \n");
if (graphURI != null) {
queryBuff.append(" GRAPH <" + graphURI + "> { \n");
@ -190,10 +242,23 @@ public class RDFServiceSDB extends RDFServiceImpl implements RDFService {
//log.debug(queryBuff.toString());
GraphStore graphStore = GraphStoreFactory.create(dataset);
UpdateRequest request = UpdateFactory.create();
request.add(queryBuff.toString());
UpdateAction.execute(request, graphStore);
Query construct = QueryFactory.create(queryBuff.toString());
// make a plain dataset to force the query to be run in a way that
// won't overwhelm MySQL with too many joins
DataSource ds = DatasetFactory.create();
ds.addNamedModel(graphURI, (graphURI != null)
? dataset.getNamedModel(graphURI) : dataset.getDefaultModel());
QueryExecution qe = QueryExecutionFactory.create(construct, ds);
try {
Model m = qe.execConstruct();
if (graphURI != null) {
dataset.getNamedModel(graphURI).remove(m);
} else {
dataset.getDefaultModel().remove(m);
}
} finally {
qe.close();
}
}
private Model parseModel(ModelChange modelChange) {

View file

@ -14,6 +14,7 @@ import com.hp.hpl.jena.ontology.AnnotationProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
@ -25,6 +26,7 @@ import com.hp.hpl.jena.rdf.listeners.StatementListener;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
@ -32,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.JenaException;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
@ -126,12 +129,13 @@ public class SimpleReasoner extends StatementListener {
*/
@Override
public void addedStatement(Statement stmt) {
try {
if (stmt.getPredicate().equals(RDF.type)) {
addedABoxTypeAssertion(stmt, inferenceModel, new HashSet<String>());
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
}
} else {
addedABoxAssertion(stmt, inferenceModel);
}
doPlugins(ModelUpdate.Operation.ADD,stmt);
@ -150,8 +154,9 @@ public class SimpleReasoner extends StatementListener {
public void removedStatement(Statement stmt) {
try {
if (!isInterestedInRemovedStatement(stmt)) { return; }
// if (!isInterestedInRemovedStatement(stmt)) { return; }
// interested in all of them now that we are doing inverse
// property reasoning
handleRemovedStatement(stmt);
} catch (Exception e) {
@ -160,7 +165,6 @@ public class SimpleReasoner extends StatementListener {
}
}
/*
* Synchronized part of removedStatement. Interacts
* with DeltaComputer.
@ -175,7 +179,9 @@ public class SimpleReasoner extends StatementListener {
if (stmt.getPredicate().equals(RDF.type)) {
removedABoxTypeAssertion(stmt, inferenceModel);
setMostSpecificTypes(stmt.getSubject(), inferenceModel, new HashSet<String>());
}
} else {
removedABoxAssertion(stmt, inferenceModel);
}
doPlugins(ModelUpdate.Operation.RETRACT,stmt);
}
}
@ -184,29 +190,32 @@ public class SimpleReasoner extends StatementListener {
* Performs incremental ABox reasoning based
* on changes to the class hierarchy.
*
* Handles rdfs:subclassOf, owl:equivalentClass,
* Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf
*/
public void addedTBoxStatement(Statement stmt) {
try {
if (!(stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) || stmt.getPredicate().equals(OWL.inverseOf))) {
return;
}
try {
log.debug("added TBox assertion = " + stmt.toString());
log.debug("added TBox assertion = " + stmt.toString());
if ( stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) ) {
if ( stmt.getObject().isResource() && (stmt.getObject().asResource()).getURI() == null ) {
log.warn("The object of this assertion has a null URI: " + stmtString(stmt));
return;
}
if ( stmt.getSubject().getURI() == null ) {
log.warn("The subject of this assertion has a null URI: " + stmtString(stmt));
return;
}
if (stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass)) {
// ignore anonymous classes
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
return;
}
if ( stmt.getObject().isResource() && (stmt.getObject().asResource()).getURI() == null ) {
log.warn("The object of this assertion has a null URI: " + stmtString(stmt));
return;
}
if ( stmt.getSubject().getURI() == null ) {
log.warn("The subject of this assertion has a null URI: " + stmtString(stmt));
return;
}
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
if (subject == null) {
log.debug("didn't find subject class in the tbox: " + (stmt.getSubject()).getURI());
@ -220,13 +229,27 @@ public class SimpleReasoner extends StatementListener {
}
if (stmt.getPredicate().equals(RDFS.subClassOf)) {
addedSubClass(subject,object,inferenceModel);
addedSubClass(subject,object,inferenceModel);
} else {
// equivalent class is the same as subclass in both directions
addedSubClass(subject,object,inferenceModel);
addedSubClass(object,subject,inferenceModel);
// equivalent class is the same as subclass in both directions
addedSubClass(subject,object,inferenceModel);
addedSubClass(object,subject,inferenceModel);
}
} else {
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
if (prop1 == null) {
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
return;
}
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
if (prop2 == null) {
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
return;
}
}
addedInverseProperty(prop1, prop2, inferenceModel);
}
} catch (Exception e) {
// don't stop the edit if there's an exception
log.error("Exception while adding inference(s): " + e.getMessage());
@ -237,29 +260,33 @@ public class SimpleReasoner extends StatementListener {
* Performs incremental ABox reasoning based
* on changes to the class hierarchy.
*
* Handles rdfs:subclassOf, owl:equivalentClass,
* Handles rdfs:subclassOf, owl:equivalentClass, and owl:inverseOf
*/
public void removedTBoxStatement(Statement stmt) {
public void removedTBoxStatement(Statement stmt) {
try {
log.debug("removed TBox assertion = " + stmt.toString());
if (!(stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) || stmt.getPredicate().equals(OWL.inverseOf))) {
return;
}
log.debug("removed TBox assertion = " + stmt.toString());
if ( stmt.getObject().isResource() && (stmt.getObject().asResource()).getURI() == null ) {
log.warn("The object of this assertion has a null URI: " + stmtString(stmt));
return;
}
if ( stmt.getSubject().getURI() == null ) {
log.warn("The subject of this assertion has a null URI: " + stmtString(stmt));
return;
}
if ( stmt.getPredicate().equals(RDFS.subClassOf) || stmt.getPredicate().equals(OWL.equivalentClass) ) {
// ignore anonymous classes
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
return;
}
if ( stmt.getObject().isResource() && (stmt.getObject().asResource()).getURI() == null ) {
log.warn("The object of this assertion has a null URI: " + stmtString(stmt));
return;
}
if ( stmt.getSubject().getURI() == null ) {
log.warn("The subject of this assertion has a null URI: " + stmtString(stmt));
return;
}
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
if (subject == null) {
log.debug("didn't find subject class in the tbox: " + (stmt.getSubject()).getURI());
@ -279,7 +306,21 @@ public class SimpleReasoner extends StatementListener {
removedSubClass(subject,object,inferenceModel);
removedSubClass(object,subject,inferenceModel);
}
}
} else {
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
if (prop1 == null) {
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
return;
}
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
if (prop2 == null) {
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
return;
}
removedInverseProperty(prop1, prop2, inferenceModel);
}
} catch (Exception e) {
// don't stop the edit if there's an exception
log.error("Exception while removing inference(s): " + e.getMessage());
@ -376,6 +417,45 @@ public class SimpleReasoner extends StatementListener {
}
}
/*
* Performs incremental property-based reasoning.
*
* Materializes inferences based on the owl:inverseOf relationship.
*
* If it is added that x prop1 y, and prop2 is an inverseOf prop1
* then add y prop2 x to the inference graph, if it is not already in
* the assertions graph.
*/
public void addedABoxAssertion(Statement stmt, Model inferenceModel) {
List<OntProperty> inverseProperties = getInverseProperties(stmt);
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
while (inverseIter.hasNext()) {
Property inverseProp = inverseIter.next();
Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject());
aboxModel.enterCriticalSection(Lock.READ);
try {
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
if (inferenceModel.contains(stmt)) {
inferenceModel.remove(stmt);
}
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt) ) {
inferenceModel.add(infStmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
} finally {
aboxModel.leaveCriticalSection();
}
}
}
/*
* If it is removed that B is of type A, then for each superclass of A remove
* the inferred statement that B is of that type UNLESS it is otherwise entailed
@ -386,8 +466,7 @@ public class SimpleReasoner extends StatementListener {
tboxModel.enterCriticalSection(Lock.READ);
try {
try {
OntClass cls = null;
if ( (stmt.getObject().asResource()).getURI() != null ) {
@ -453,13 +532,50 @@ public class SimpleReasoner extends StatementListener {
}
}
/*
* Performs incremental property-based reasoning.
*
* Retracts inferences based on the owl:inverseOf relationship.
*
* If it is removed that x prop1 y, and prop2 is an inverseOf prop1
* then remove y prop2 x from the inference graph, unless it is
* otherwise entailed by the assertions graph independently of
* this removed statement.
*/
public void removedABoxAssertion(Statement stmt, Model inferenceModel) {
List<OntProperty> inverseProperties = getInverseProperties(stmt);
Iterator<OntProperty> inverseIter = inverseProperties.iterator();
while (inverseIter.hasNext()) {
OntProperty inverseProp = inverseIter.next();
Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject());
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
if (!entailedInverseStmt(infStmt) && inferenceModel.contains(infStmt)) {
inferenceModel.remove(infStmt);
}
// if a statement has been removed that is otherwise entailed,
// add it to the inference graph.
if (entailedInverseStmt(stmt) && !inferenceModel.contains(stmt)) {
inferenceModel.add(stmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
}
}
// Returns true if it is entailed by class subsumption that
// subject is of type cls; otherwise returns false.
protected boolean entailedType(Resource subject, OntClass cls) {
aboxModel.enterCriticalSection(Lock.READ);
tboxModel.enterCriticalSection(Lock.READ);
aboxModel.enterCriticalSection(Lock.READ);
try {
try {
List<OntClass> subclasses = null;
subclasses = (cls.listSubClasses(false)).toList();
subclasses.addAll((cls.listEquivalentClasses()).toList());
@ -477,12 +593,101 @@ public class SimpleReasoner extends StatementListener {
} catch (Exception e) {
log.debug("exception in method entailedType: " + e.getMessage());
return false;
} finally {
} finally {
aboxModel.leaveCriticalSection();
tboxModel.leaveCriticalSection();
}
}
// Returns true if the triple is entailed by inverse property
// reasoning; otherwise returns false.
protected boolean entailedInverseStmt(Statement stmt) {
ExtendedIterator <? extends OntProperty> iter = null;
tboxModel.enterCriticalSection(Lock.READ);
try {
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().asResource().getURI());
iter = prop.listInverse();
} finally {
tboxModel.leaveCriticalSection();
}
aboxModel.enterCriticalSection(Lock.READ);
try {
while (iter.hasNext()) {
Property invProp = iter.next();
// not reasoning on properties in the OWL, RDF or RDFS namespace
if ((invProp.getNameSpace()).equals(OWL.NS) ||
(invProp.getNameSpace()).equals(RDFS.getURI()) ||
(invProp.getNameSpace()).equals(RDF.getURI())) {
continue;
}
Statement invStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), invProp, stmt.getSubject());
if (aboxModel.contains(invStmt)) {
return true;
}
}
return false;
} finally {
aboxModel.leaveCriticalSection();
}
}
/*
* Returns a list of properties that are inverses of the property
* in the given statement.
*/
protected List<OntProperty> getInverseProperties(Statement stmt) {
List<OntProperty> inverses = new ArrayList<OntProperty>();
if (stmt.getSubject().isAnon() || stmt.getObject().isAnon()) {
return inverses;
}
tboxModel.enterCriticalSection(Lock.READ);
try {
OntProperty prop = tboxModel.getOntProperty(stmt.getPredicate().getURI());
if (prop != null) {
if (!prop.isObjectProperty()) {
return inverses;
}
if (!stmt.getObject().isResource()) {
log.warn("The predicate of this statement is an object property, but the object is not a resource.");
return inverses;
}
// not reasoning on properties in the OWL, RDF or RDFS namespace
if ((prop.getNameSpace()).equals(OWL.NS) ||
(prop.getNameSpace()).equals(RDFS.getURI()) ||
(prop.getNameSpace()).equals(RDF.getURI())) {
return inverses;
}
ExtendedIterator <? extends OntProperty> iter = prop.listInverse();
while (iter.hasNext()) {
OntProperty invProp = iter.next();
if ((invProp.getNameSpace()).equals(OWL.NS) ||
(invProp.getNameSpace()).equals(RDFS.getURI()) ||
(invProp.getNameSpace()).equals(RDF.getURI())) {
continue;
}
inverses.add(invProp);
}
}
} finally {
tboxModel.leaveCriticalSection();
}
return inverses;
}
/*
* If it is added that B is a subClass of A, then for each
* individual that is typed as B, either in the ABox or in the
@ -566,6 +771,112 @@ public class SimpleReasoner extends StatementListener {
}
}
/*
* If it is added that P is an inverse of Q, then:
* 1. For each statement involving predicate P in
* the assertions model add the inverse statement
* to the inference model if that inverse is
* in the assertions model.
*
* 2. Repeat the same for predicate Q.
*
*/
public void addedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) {
if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) {
log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI());
return;
}
Model inferences = ModelFactory.createDefaultModel();
inferences.add(generateInverseInferences(prop1, prop2));
inferences.add(generateInverseInferences(prop2, prop1));
if (inferences.isEmpty()) return;
aboxModel.enterCriticalSection(Lock.READ);
try {
StmtIterator iter = inferences.listStatements();
while (iter.hasNext()) {
Statement infStmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
if (!inferenceModel.contains(infStmt) && !aboxModel.contains(infStmt)) {
inferenceModel.add(infStmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
}
} finally {
aboxModel.leaveCriticalSection();
}
}
public Model generateInverseInferences(OntProperty prop, OntProperty inverseProp) {
Model inferences = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.READ);
try {
StmtIterator iter = aboxModel.listStatements((Resource) null, prop, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
if (!stmt.getObject().isResource()) continue;
Statement infStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), inverseProp, stmt.getSubject());
inferences.add(infStmt);
}
} finally {
aboxModel.leaveCriticalSection();
}
return inferences;
}
/*
* If it is removed that P is an inverse of Q, then:
* 1. For each statement involving predicate P in
* the abox assertions model remove the inverse
* statement from the inference model unless
* that statement is otherwise entailed.
*
* 2. Repeat the same for predicate Q.
*/
public void removedInverseProperty(OntProperty prop1, OntProperty prop2, Model inferenceModel) {
if ( !prop1.isObjectProperty() || !prop2.isObjectProperty() ) {
log.warn("The subject and object of the inverseOf statement are not both object properties. No inferencing will be performed. property 1: " + prop1.getURI() + " property 2:" + prop2.getURI());
return;
}
Model inferences = ModelFactory.createDefaultModel();
inferences.add(generateInverseInferences(prop1, prop2));
inferences.add(generateInverseInferences(prop2, prop1));
if (inferences.isEmpty()) return;
StmtIterator iter = inferences.listStatements();
while (iter.hasNext()) {
Statement infStmt = iter.next();
if (entailedInverseStmt(infStmt)) {
continue;
}
inferenceModel.enterCriticalSection(Lock.WRITE);
try {
if (inferenceModel.contains(infStmt)) {
inferenceModel.remove(infStmt);
}
} finally {
inferenceModel.leaveCriticalSection();
}
}
}
/*
* Find the most specific types (classes) of an individual and
* indicate them for the individual with the mostSpecificType
@ -740,13 +1051,12 @@ public class SimpleReasoner extends StatementListener {
* inference models.
*/
protected synchronized void recomputeABox() {
HashSet<String> unknownTypes = new HashSet<String>();
// recompute the inferences
inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
try {
log.info("Computing class-based ABox inferences.");
log.info("Computing ABox inferences.");
inferenceRebuildModel.removeAll();
int numStmts = 0;
@ -784,6 +1094,57 @@ public class SimpleReasoner extends StatementListener {
log.info("Still computing class-based ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
}
}
log.info("Finished computing class-based ABox inferences");
Iterator<Statement> invStatements = null;
tboxModel.enterCriticalSection(Lock.READ);
try {
invStatements = tboxModel.listStatements((Resource) null, OWL.inverseOf, (Resource) null);
} finally {
tboxModel.leaveCriticalSection();
}
while (invStatements.hasNext()) {
Statement stmt = invStatements.next();
try {
OntProperty prop1 = tboxModel.getOntProperty((stmt.getSubject()).getURI());
if (prop1 == null) {
log.debug("didn't find subject property in the tbox: " + (stmt.getSubject()).getURI());
continue;
}
OntProperty prop2 = tboxModel.getOntProperty(((Resource)stmt.getObject()).getURI());
if (prop2 == null) {
log.debug("didn't find object property in the tbox: " + ((Resource)stmt.getObject()).getURI());
continue;
}
addedInverseProperty(prop1, prop2, inferenceRebuildModel);
} catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
return;
} catch (JenaException je) {
if (je.getMessage().equals("Statement models must no be null")) {
log.error("Exception while recomputing ABox inference model. Halting inference computation.", je);
return;
}
log.error("Exception while recomputing ABox inference model: ", je);
} catch (Exception e) {
log.error("Exception while recomputing ABox inference model: ", e);
}
numStmts++;
if ((numStmts % 10000) == 0) {
log.info("Still computing property-based ABox inferences...");
}
if (stopRequested) {
log.info("a stopRequested signal was received during recomputeABox. Halting Processing.");
return;
@ -798,7 +1159,7 @@ public class SimpleReasoner extends StatementListener {
inferenceRebuildModel.leaveCriticalSection();
}
log.info("Finished computing class-based ABox inferences");
log.info("Finished computing property-based ABox inferences");
// reflect the recomputed inferences into the application
// inference model.
@ -983,9 +1344,9 @@ public class SimpleReasoner extends StatementListener {
}
break;
}
} catch (Throwable t) {
} catch (Exception e) {
log.error("Exception while processing " + (op == ModelUpdate.Operation.ADD ? "an added" : "a removed") +
" statement in SimpleReasoner plugin:" + plugin.getClass().getName() + " -- " + t.getMessage());
" statement in SimpleReasoner plugin:" + plugin.getClass().getName() + " -- " + e.getMessage());
}
}
}

View file

@ -3,6 +3,7 @@
package edu.cornell.mannlib.vitro.webapp.search.controller;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -51,6 +52,7 @@ import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryFactory;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.searchresult.IndividualSearchResult;
import edu.ucsf.vitro.opensocial.OpenSocialManager;
/**
* Paged search controller that uses Solr
@ -268,7 +270,24 @@ public class PagedSearchController extends FreemarkerHttpServlet {
vreq.getServletPath(), pagingLinkParams));
}
String template = templateTable.get(format).get(Result.PAGED);
// VIVO OpenSocial Extension by UCSF
try {
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "search");
// put list of people found onto pubsub channel
List<String> ids = OpenSocialManager.getOpenSocialId(individuals);
openSocialManager.setPubsubData(OpenSocialManager.JSON_PERSONID_CHANNEL,
OpenSocialManager.buildJSONPersonIds(ids, "" + ids.size() + " people found"));
body.put("openSocial", openSocialManager);
if (openSocialManager.isVisible()) {
body.put("bodyOnload", "my.init();");
}
} catch (IOException e) {
log.error("IOException in doTemplate()", e);
} catch (SQLException e) {
log.error("SQLException in doTemplate()", e);
}
String template = templateTable.get(format).get(Result.PAGED);
return new TemplateResponseValues(template, body);
} catch (Throwable e) {

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
*/
public class UserModelSetup extends JenaDataSourceSetupBase
implements ServletContextListener {
protected static String AUTHPATH = BASE + "auth/";
private static final Log log = LogFactory.getLog(
UserModelSetup.class.getName());
@ -55,7 +56,12 @@ public class UserModelSetup extends JenaDataSourceSetupBase
OntModel userAccountsModel =
ModelFactory.createOntologyModel( MEM_ONT_MODEL_SPEC);
userAccountsModel.add(userAccountsDbModel);
// This is used in Selenium testing, when we load user accounts from a file.
if (userAccountsDbModel.isEmpty()) {
readOntologyFilesInPathSet(AUTHPATH, ctx, userAccountsDbModel);
}
userAccountsModel.add(userAccountsDbModel);
userAccountsModel.getBaseModel().register(
new ModelSynchronizer(userAccountsDbModel));
ctx.setAttribute("userAccountsOntModel", userAccountsModel);
@ -65,5 +71,4 @@ public class UserModelSetup extends JenaDataSourceSetupBase
ss.fatal(this, "Unable to load user accounts model from DB", t);
}
}
}

View file

@ -0,0 +1,128 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
public class FixedHTMLDataGetter extends DataGetterBase implements DataGetter{
String dataGetterURI;
String htmlValue;
String saveToVar;
VitroRequest vreq;
ServletContext context;
private final static String defaultTemplate = "menupage--defaultFixedHtml.ftl";
final static Log log = LogFactory.getLog(FixedHTMLDataGetter.class);
/**
* Constructor with display model and data getter URI that will be called by reflection.
*/
public FixedHTMLDataGetter(VitroRequest vreq, Model displayModel, String dataGetterURI){
this.configure(vreq, displayModel,dataGetterURI);
}
@Override
public Map<String, Object> getData(Map<String, Object> pageData) {
Map<String, Object> rmap = new HashMap<String,Object>();
rmap.put("variableName", this.saveToVar);
rmap.put(this.saveToVar, this.htmlValue);
//this is the default template set here - overridden by page level template if there is one
rmap.put("bodyTemplate", defaultTemplate);
return rmap;
}
/**
* Configure this instance based on the URI and display model.
*/
protected void configure(VitroRequest vreq, Model displayModel, String dataGetterURI) {
if( vreq == null )
throw new IllegalArgumentException("VitroRequest may not be null.");
if( displayModel == null )
throw new IllegalArgumentException("Display Model may not be null.");
if( dataGetterURI == null )
throw new IllegalArgumentException("PageUri may not be null.");
this.vreq = vreq;
this.context = vreq.getSession().getServletContext();
this.dataGetterURI = dataGetterURI;
QuerySolutionMap initBindings = new QuerySolutionMap();
initBindings.add("dataGetterURI", ResourceFactory.createResource(this.dataGetterURI));
int count = 0;
Query dataGetterConfigurationQuery = QueryFactory.create(dataGetterQuery) ;
displayModel.enterCriticalSection(Lock.READ);
try{
QueryExecution qexec = QueryExecutionFactory.create(
dataGetterConfigurationQuery, displayModel, initBindings) ;
ResultSet res = qexec.execSelect();
try{
while( res.hasNext() ){
count++;
QuerySolution soln = res.next();
// is NOT OPTIONAL
Literal value = soln.getLiteral("htmlValue");
if( dataGetterConfigurationQuery == null )
log.error("no html value defined for page " + this.dataGetterURI);
else
this.htmlValue = value.getLexicalForm();
//saveToVar is OPTIONAL
Literal saveTo = soln.getLiteral("saveToVar");
if( saveTo != null && saveTo.isLiteral() ){
this.saveToVar = saveTo.asLiteral().getLexicalForm();
}else{
this.saveToVar = defaultVarNameForResults;
}
}
}finally{ qexec.close(); }
}finally{ displayModel.leaveCriticalSection(); }
}
private static final String saveToVarPropertyURI= "<" + DisplayVocabulary.SAVE_TO_VAR+ ">";
private static final String htmlValuePropertyURI= "<" + DisplayVocabulary.FIXED_HTML_VALUE+ ">";
public static final String defaultVarNameForResults = "results";
/**
* Query to get the definition of the SparqlDataGetter for a given URI.
*/
private static final String dataGetterQuery =
"PREFIX display: <" + DisplayVocabulary.DISPLAY_NS +"> \n" +
"SELECT ?saveToVar ?htmlValue WHERE { \n" +
" ?dataGetterURI "+saveToVarPropertyURI+" ?saveToVar . \n" +
" ?dataGetterURI "+htmlValuePropertyURI+" ?htmlValue . \n" +
"}";
}

View file

@ -47,7 +47,8 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
String dataGetterURI;
String classGroupURI;
Map<String, Object> classIntersectionsMap;
private final static String defaultTemplate = "page-classgroup.ftl";
/**
* Constructor with display model and data getter URI that will be called by reflection.
*/
@ -132,6 +133,8 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl());
//this is the class group associated with the data getter utilized for display on menu editing, not the custom one created
data.put("classGroupUri",this.classGroupURI);
//default template, overridden at page level if specified in display model
data.put("bodyTemplate", defaultTemplate);
} catch(Exception ex) {
log.error("An error occurred retrieving Vclass Intersection individuals", ex);
}

View file

@ -37,9 +37,11 @@ public class SparqlQueryDataGetter extends DataGetterBase implements DataGetter{
String modelURI;
VitroRequest vreq;
ServletContext context;
final static Log log = LogFactory.getLog(SparqlQueryDataGetter.class);
//default template
private final static String defaultTemplate = "menupage--defaultSparql.ftl";
/**
* Constructor with display model and data getter URI that will be called by reflection.
@ -134,7 +136,9 @@ public class SparqlQueryDataGetter extends DataGetterBase implements DataGetter{
//put results in page data, what key to use for results?
Map<String, Object> rmap = new HashMap<String,Object>();
rmap.put(this.saveToVar, results);
rmap.put(this.saveToVar, results);
//This will be overridden at page level in display model if template specified there
rmap.put("bodyTemplate", defaultTemplate);
return rmap;
}

View file

@ -0,0 +1,159 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DataPropertyTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DataPropertyTemplateModel.ConfigError;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
public class DataPropertyListConfig {
private static final Log log = LogFactory.getLog(DataPropertyListConfig.class);
private static final String CONFIG_FILE_PATH = "/config/";
private static final String DEFAULT_CONFIG_FILE_NAME = "listViewConfig-dataDefault.xml";
/* NB The default post-processor is not the same as the post-processor for the default view. The latter
* actually defines its own post-processor, whereas the default post-processor is used for custom views
* that don't define a post-processor, to ensure that the standard post-processing applies.
*
* edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultObjectPropertyDataPostProcessor
*/
// TODO Lump these together into the PropertyListConfigContext
private final DataPropertyTemplateModel dptm;
private final VitroRequest vreq;
private final TemplateLoader templateLoader;
private boolean isDefaultConfig;
private Set<String> constructQueries;
private String selectQuery;
private String templateName;
public DataPropertyListConfig(DataPropertyTemplateModel dptm, TemplateLoader templateLoader, VitroRequest vreq,
DataProperty dp, boolean editing)
throws InvalidConfigurationException {
this.dptm = dptm;
this.vreq = vreq;
WebappDaoFactory wadf = vreq.getWebappDaoFactory();
this.templateLoader = templateLoader;
// Get the custom config filename
String configFileName = wadf.getDataPropertyDao().getCustomListViewConfigFileName(dp);
if (configFileName == null) { // no custom config; use default config
configFileName = DEFAULT_CONFIG_FILE_NAME;
}
log.debug("Using list view config file " + configFileName + " for data property " + dp.getURI());
String configFilePath = getConfigFilePath(configFileName);
try {
File config = new File(configFilePath);
if ( ! isDefaultConfig(configFileName) && ! config.exists() ) {
log.warn("Can't find config file " + configFilePath + " for data property " + dp.getURI() + "\n" +
". Using default config file instead.");
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
// Should we test for the existence of the default, and throw an error if it doesn't exist?
}
setValuesFromConfigFile(configFilePath, wadf, editing);
} catch (Exception e) {
log.error("Error processing config file " + configFilePath + " for data property " + dp.getURI(), e);
// What should we do here?
}
if ( ! isDefaultConfig(configFileName) ) {
ConfigError configError = checkConfiguration();
if ( configError != null ) { // the configuration contains an error
log.warn("Invalid list view config for data property " + dp.getURI() +
" in " + configFilePath + ":\n" +
configError + " Using default config instead.");
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
setValuesFromConfigFile(configFilePath, wadf, editing);
}
}
isDefaultConfig = isDefaultConfig(configFileName);
}
private boolean isDefaultConfig(String configFileName) {
return configFileName.equals(DEFAULT_CONFIG_FILE_NAME);
}
private ConfigError checkConfiguration() {
ConfigError error = dptm.checkQuery(selectQuery);
if (error != null) {
return error;
}
if (StringUtils.isBlank(selectQuery)) {
return ConfigError.NO_SELECT_QUERY;
}
if ( StringUtils.isBlank(templateName)) {
return ConfigError.NO_TEMPLATE;
}
try {
if ( templateLoader.findTemplateSource(templateName) == null ) {
return ConfigError.TEMPLATE_NOT_FOUND;
}
} catch (IOException e) {
log.error("Error finding template " + templateName, e);
}
return null;
}
private void setValuesFromConfigFile(String configFilePath, WebappDaoFactory wdf,
boolean editing) {
try {
FileReader reader = new FileReader(configFilePath);
CustomListViewConfigFile configFileContents = new CustomListViewConfigFile(reader);
selectQuery = configFileContents.getSelectQuery(false, editing);
templateName = configFileContents.getTemplateName();
constructQueries = configFileContents.getConstructQueries();
} catch (Exception e) {
log.error("Error processing config file " + configFilePath, e);
}
}
private String getConfigFilePath(String filename) {
return vreq.getSession().getServletContext().getRealPath(CONFIG_FILE_PATH + filename);
}
public String getSelectQuery() {
return this.selectQuery;
}
public Set<String> getConstructQueries() {
return this.constructQueries;
}
public String getTemplateName() {
return this.templateName;
}
public boolean isDefaultListView() {
return this.isDefaultConfig;
}
}

View file

@ -25,13 +25,15 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
private final Literal literalValue;
private final String deleteUrl;
private final String editUrl;
private final String templateName;
//Extended to include vitro request to check for special parameters
public DataPropertyStatementTemplateModel(String subjectUri, String propertyUri,
Literal literal, VitroRequest vreq) {
public DataPropertyStatementTemplateModel(String subjectUri, String propertyUri, Literal literal,
String templateName, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
this.literalValue = literal;
this.templateName = templateName;
// Do delete url first, since used in building edit url
this.deleteUrl = makeDeleteUrl();
@ -52,6 +54,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
"datapropKey", makeHash(dps),
"cmd", "delete");
params.put("templateName", templateName);
params.putAll(UrlBuilder.getModelParams(vreq));
return UrlBuilder.getUrl(EDIT_PATH, params);

View file

@ -4,7 +4,11 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -17,11 +21,15 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.DataPropertyListConfig;
import freemarker.cache.TemplateLoader;
public class DataPropertyTemplateModel extends PropertyTemplateModel {
@ -31,6 +39,33 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
private static final String EDIT_PATH = "editRequestDispatch";
private final List<DataPropertyStatementTemplateModel> statements;
private static final String KEY_SUBJECT = "subject";
private static final String KEY_PROPERTY = "property";
public static enum ConfigError {
NO_SELECT_QUERY("Missing select query specification"),
NO_TEMPLATE("Missing template specification"),
TEMPLATE_NOT_FOUND("Specified template does not exist");
String message;
ConfigError(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public String toString() {
return getMessage();
}
}
private DataPropertyListConfig config;
private String objectKey;
private String queryString;
private Set<String> constructQueries;
DataPropertyTemplateModel(DataProperty dp, Individual subject, VitroRequest vreq,
boolean editing, List<DataProperty> populatedDataPropertyList) {
@ -38,15 +73,25 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
super(dp, subject, vreq);
setName(dp.getPublicName());
// Get the config for this data property
try {
config = new DataPropertyListConfig(this, getFreemarkerTemplateLoader(), vreq, dp, editing);
} catch (Exception e) {
log.error(e, e);
}
queryString = getSelectQuery();
constructQueries = getConstructQueries();
statements = new ArrayList<DataPropertyStatementTemplateModel>();
// If the property is populated, get the data property statements via a sparql query
if (populatedDataPropertyList.contains(dp)) {
log.debug("Getting data for populated data property " + getUri());
DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao();
List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp);
List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp, queryString, constructQueries);
for (Literal value : values) {
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, vreq));
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, getTemplateName(), vreq));
}
} else {
log.debug("Data property " + getUri() + " is unpopulated.");
@ -57,7 +102,6 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
}
}
protected void setAddUrl(Property property) {
DataProperty dp = (DataProperty) property;
@ -91,6 +135,10 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
addUrl = UrlBuilder.getUrl(EDIT_PATH, params);
}
protected TemplateLoader getFreemarkerTemplateLoader() {
return FreemarkerConfigurationLoader.getConfig(vreq).getTemplateLoader();
}
@Override
protected int getPropertyDisplayTier(Property p) {
return ((DataProperty)p).getDisplayTier();
@ -101,6 +149,37 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
return Route.DATA_PROPERTY_EDIT;
}
public ConfigError checkQuery(String queryString) {
if (StringUtils.isBlank(queryString)) {
return ConfigError.NO_SELECT_QUERY;
}
return null;
}
private String getSelectQuery() {
return config.getSelectQuery();
}
private Set<String> getConstructQueries() {
return config.getConstructQueries();
}
protected String getTemplateName() {
return config.getTemplateName();
}
protected boolean hasDefaultListView() {
return config.isDefaultListView();
}
protected String getObjectKey() {
return objectKey;
}
protected boolean isEmpty() {
return statements.isEmpty();
}
/* Template properties */
public String getType() {
@ -111,6 +190,9 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
return statements;
}
public String getTemplate() {
return getTemplateName();
}
/* Template methods */

View file

@ -34,7 +34,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String objectKey,
Map<String, String> data, String templateName, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
this.data = Collections.unmodifiableMap(new HashMap<String, String>(data));
this.objectUri = data.get(objectKey);
this.templateName = templateName;

View file

@ -0,0 +1,100 @@
package edu.ucsf.vitro.opensocial;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
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;
public class GadgetController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(GadgetController.class);
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
if (vreq.getServletPath().endsWith("/sandbox")) {
boolean sandbox = "True".equalsIgnoreCase(ConfigurationProperties.getBean(vreq.getSession()
.getServletContext()).getProperty("OpenSocial.sandbox"));
if (!sandbox) {
return new ExceptionResponseValues( new Exception("Sandbox not available"));
}
return processGadgetSandbox(vreq);
}
else {
return processGadgetDetails(vreq);
}
}
protected ResponseValues processGadgetDetails(VitroRequest vreq) {
try {
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Gadget Details");
// VIVO OpenSocial Extension by UCSF
try {
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "gadgetDetails");
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
if (openSocialManager.isVisible()) {
body.put("bodyOnload", "my.init();");
}
} catch (IOException e) {
log.error("IOException in doTemplate()", e);
} catch (SQLException e) {
log.error("SQLException in doTemplate()", e);
}
return new TemplateResponseValues("gadgetDetails.ftl", body);
} catch (Throwable e) {
log.error(e, e);
return new ExceptionResponseValues(e);
}
}
@Override
protected String getTitle(String siteName, VitroRequest vreq) {
return "Gadget Details";
}
protected ResponseValues processGadgetSandbox(VitroRequest vreq) {
if ("POST".equalsIgnoreCase(vreq.getMethod())) {
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_GADGETS, vreq.getParameter("gadgetURLS"));
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_DEBUG, vreq.getParameter("debug") != null);
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_NOCACHE, vreq.getParameter("useCache") == null);
return new RedirectResponseValues("/");
}
Map<String, Object> body = new HashMap<String, Object>();
body.put("title", "Gadget Sandbox");
try {
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "gadgetSandbox");
String gadgetURLS = "";
for (PreparedGadget gadget : openSocialManager.getVisibleGadgets())
{
gadgetURLS += gadget.getGadgetURL() + System.getProperty("line.separator");
}
body.put("gadgetURLS", gadgetURLS);
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
} catch (IOException e) {
log.error("IOException in doTemplate()", e);
} catch (SQLException e) {
log.error("SQLException in doTemplate()", e);
}
return new TemplateResponseValues("gadgetLogin.ftl", body);
}
}

View file

@ -0,0 +1,204 @@
package edu.ucsf.vitro.opensocial;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbcp.BasicDataSource;
public class GadgetSpec {
private String openSocialGadgetURL;
private String name;
private int appId = 0;
private List<String> channels = new ArrayList<String>();
private boolean unknownGadget = false;
private Map<String, GadgetViewRequirements> viewRequirements = new HashMap<String, GadgetViewRequirements>();
// For preloading
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
List<String> channels) {
this.appId = appId;
this.name = name;
this.openSocialGadgetURL = openSocialGadgetURL;
this.channels.addAll(channels);
}
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
String channelsStr) {
this(appId, name, openSocialGadgetURL, Arrays.asList(channelsStr != null
&& channelsStr.length() > 0 ? channelsStr.split(" ") : new String[0]));
}
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
List<String> channels, boolean unknownGadget, BasicDataSource ds)
throws SQLException {
this(appId, name, openSocialGadgetURL, channels);
this.unknownGadget = unknownGadget;
// Load gadgets from the DB first
if (!unknownGadget) {
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
try {
String sqlCommand = "select page, viewer_req, owner_req, view, closed_width, open_width, start_closed, chromeId, display_order from shindig_app_views where appId = "
+ appId;
conn = ds.getConnection();
stmt = conn.createStatement();
rset = stmt.executeQuery(sqlCommand);
while (rset.next()) {
viewRequirements.put(
rset.getString(1),
new GadgetViewRequirements(rset.getString(1), rset
.getString(2), rset.getString(3), rset
.getString(4), rset.getInt(5), rset
.getInt(6), rset.getBoolean(7), rset
.getString(8), rset.getInt(9)));
}
} finally {
try {
if (rset != null) {
rset.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (stmt != null) {
stmt.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public int getAppId() {
return appId;
}
public String getName() {
return name;
}
public String getGadgetURL() {
return openSocialGadgetURL;
}
public List<String> getChannels() {
return channels;
}
public boolean listensTo(String channel) { // if an unknown gadget just say yes,
// we don't care about
// performance in this situation
return unknownGadget || channels.contains(channel);
}
public GadgetViewRequirements getGadgetViewRequirements(String page) {
if (viewRequirements.containsKey(page)) {
return viewRequirements.get(page);
}
return null;
}
public boolean show(String viewerId, String ownerId, String page,
BasicDataSource ds) throws SQLException {
boolean show = true;
// if there are no view requirements, go ahead and show it. We are
// likely testing out a new gadget
// if there are some, turn it off unless this page is
if (viewRequirements.size() > 0) {
show = false;
}
if (viewRequirements.containsKey(page)) {
show = true;
GadgetViewRequirements req = getGadgetViewRequirements(page);
if ('U' == req.getViewerReq() && viewerId != null) {
show = false;
} else if ('R' == req.getViewerReq()) {
show &= isRegisteredTo(viewerId, ds);
}
if ('R' == req.getOwnerReq()) {
show &= isRegisteredTo(ownerId, ds);
} else if ('S' == req.getOwnerReq()) {
show &= (viewerId == ownerId);
}
}
return show;
}
public boolean isRegisteredTo(String personId, BasicDataSource ds)
throws SQLException {
int count = 0;
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
try {
String sqlCommand = "select count(*) from shindig_app_registry where appId = "
+ getAppId() + " and personId = '" + personId + "';";
conn = ds.getConnection();
stmt = conn.createStatement();
rset = stmt.executeQuery(sqlCommand);
while (rset.next()) {
count = rset.getInt(1);
}
} finally {
try {
if (rset != null) {
rset.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (stmt != null) {
stmt.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return (count == 1);
}
public boolean fromSandbox() {
return unknownGadget;
}
// who sees it? Return the viewerReq for the ProfileDetails page
public char getVisibleScope() {
GadgetViewRequirements req = getGadgetViewRequirements("/display");
return req != null ? req.getViewerReq() : ' ';
}
public String toString() {
return "" + this.appId + ":" + this.name + ":" + this.openSocialGadgetURL;
}
}

View file

@ -0,0 +1,67 @@
package edu.ucsf.vitro.opensocial;
public class GadgetViewRequirements {
private String page;
private char viewerReq; // U for User or null for no requirement
private char ownerReq; // R for Registered or null for no requirement
private String view;
private int closedWidth;
private int openWidth;
private boolean startClosed;
private String chromeId;
private int display_order;
public GadgetViewRequirements(String page, char viewerReq, char ownerReq,
String view, int closedWidth, int openWidth, boolean startClosed,
String chromeId, int display_order) {
this.page = page;
this.viewerReq = viewerReq;
this.ownerReq = ownerReq;
this.view = view;
this.closedWidth = closedWidth;
this.openWidth = openWidth;
this.startClosed = startClosed;
this.chromeId = chromeId;
this.display_order = display_order;
}
public GadgetViewRequirements(String page, String viewerReq,
String ownerReq, String view, int closedWidth, int openWidth,
boolean startClosed, String chromeId, int display_order) {
this(page, viewerReq != null ? viewerReq.charAt(0) : ' ',
ownerReq != null ? ownerReq.charAt(0) : ' ', view, closedWidth,
openWidth, startClosed, chromeId, display_order);
}
public char getViewerReq() {
return viewerReq;
}
public char getOwnerReq() {
return ownerReq;
}
public String getView() {
return view;
}
public int getClosedWidth() {
return closedWidth;
}
public int getOpenWidth() {
return openWidth;
}
public boolean getStartClosed() {
return startClosed;
}
public String getChromeId() {
return chromeId;
}
int getDisplayOrder() {
return display_order;
}
}

View file

@ -0,0 +1,483 @@
package edu.ucsf.vitro.opensocial;
import java.io.IOException;
import java.net.Socket;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbcp.BasicDataSource;
import org.json.JSONException;
import org.json.JSONObject;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestAnalysisContextImpl;
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestAnalyzer;
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestInfo;
public class OpenSocialManager {
public static final String SHINDIG_URL_PROP = "OpenSocial.shindigURL";
public static final String OPENSOCIAL_DEBUG = "OPENSOCIAL_DEBUG";
public static final String OPENSOCIAL_NOCACHE = "OPENSOCIAL_NOCACHE";
public static final String OPENSOCIAL_GADGETS = "OPENSOCIAL_GADGETS";
public static final String JSON_PERSONID_CHANNEL = "JSONPersonIds";
public static final String JSON_PMID_CHANNEL = "JSONPubMedIds";
public static final String TAG_NAME = "openSocial";
private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private List<PreparedGadget> gadgets = new ArrayList<PreparedGadget>();
private Map<String, String> pubsubdata = new HashMap<String, String>();
private String viewerId = null;
private String ownerId = null;
private boolean isDebug = false;
private boolean noCache = false;
private String pageName;
private ConfigurationProperties configuration;
private BasicDataSource dataSource;
public OpenSocialManager(VitroRequest vreq, String pageName) throws SQLException, IOException {
this(vreq, pageName, false);
}
public OpenSocialManager(VitroRequest vreq, String pageName, boolean editMode) throws SQLException, IOException {
this.isDebug = vreq.getSession() != null
&& Boolean.TRUE.equals(vreq.getSession().getAttribute(OPENSOCIAL_DEBUG));
this.noCache = vreq.getSession() != null
&& Boolean.TRUE.equals(vreq.getSession().getAttribute(OPENSOCIAL_NOCACHE));
this.pageName = pageName;
configuration = ConfigurationProperties.getBean(vreq.getSession()
.getServletContext());
if (configuration.getProperty(SHINDIG_URL_PROP) == null) {
// do nothing
return;
}
// Analyze the request to figure out whose page we are viewing.
this.ownerId = figureOwnerId(vreq);
// in editMode we need to set the viewer to be the same as the owner
// otherwise, the gadget will not be able to save appData correctly
if (editMode) {
this.viewerId = ownerId;
}
else {
UserAccount viewer = LoginStatusBean.getCurrentUser(vreq);
this.viewerId = viewer != null ? viewer.getUri() : null;
}
boolean gadgetSandbox = "gadgetSandbox".equals(pageName);
String requestAppId = vreq.getParameter("appId");
Map<String, GadgetSpec> dbApps = new HashMap<String, GadgetSpec>();
Map<String, GadgetSpec> officialApps = new HashMap<String, GadgetSpec>();
dataSource = new BasicDataSource();
dataSource.setDriverClassName(DEFAULT_DRIVER);
dataSource.setUsername(configuration
.getProperty("VitroConnection.DataSource.username"));
dataSource.setPassword(configuration
.getProperty("VitroConnection.DataSource.password"));
dataSource.setUrl(configuration
.getProperty("VitroConnection.DataSource.url"));
// Load gadgets from the DB first
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
try {
String sqlCommand = "select appId, name, url, channels, enabled from shindig_apps";
// if a specific app is requested, only grab it
if (requestAppId != null) {
sqlCommand += " where appId = " + requestAppId;
}
conn = dataSource.getConnection();
stmt = conn.createStatement();
rset = stmt.executeQuery(sqlCommand);
while (rset.next()) {
GadgetSpec spec = new GadgetSpec(rset.getInt(1),
rset.getString(2), rset.getString(3), rset.getString(4));
String gadgetFileName = getGadgetFileNameFromURL(rset
.getString(3));
dbApps.put(gadgetFileName, spec);
if (requestAppId != null || rset.getBoolean(5)) {
officialApps.put(gadgetFileName, spec);
}
}
} finally {
try {
if (rset != null) {
rset.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (stmt != null) {
stmt.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Add manual gadgets if there are any
// Note that this block of code only gets executed after someone fills in the
// gadget/sandbox form!
int moduleId = 0;
if (vreq.getSession() != null
&& vreq.getSession().getAttribute(OPENSOCIAL_GADGETS) != null) {
String openSocialGadgetURLS = (String) vreq.getSession()
.getAttribute(OPENSOCIAL_GADGETS);
String[] urls = openSocialGadgetURLS.split(System.getProperty("line.separator"));
for (String openSocialGadgetURL : urls) {
if (openSocialGadgetURL.length() == 0)
continue;
int appId = 0; // if URL matches one in the DB, use DB provided
// appId, otherwise generate one
String gadgetFileName = getGadgetFileNameFromURL(openSocialGadgetURL);
String name = gadgetFileName;
List<String> channels = new ArrayList<String>();
boolean unknownGadget = true;
if (dbApps.containsKey(gadgetFileName)) {
appId = dbApps.get(gadgetFileName).getAppId();
name = dbApps.get(gadgetFileName).getName();
channels = dbApps.get(gadgetFileName).getChannels();
unknownGadget = false;
} else {
appId = openSocialGadgetURL.hashCode();
}
// if they asked for a specific one, only let it in
if (requestAppId != null
&& Integer.getInteger(requestAppId) != appId) {
continue;
}
GadgetSpec gadget = new GadgetSpec(appId, name,
openSocialGadgetURL, channels, unknownGadget, dataSource);
// only add ones that are visible in this context!
if (unknownGadget
|| gadget.show(viewerId, ownerId, pageName, dataSource)) {
String securityToken = socketSendReceive(viewerId, ownerId,
"" + gadget.getAppId());
gadgets.add(new PreparedGadget(gadget, this, moduleId++,
securityToken));
}
}
}
// if no manual one were added, use the ones from the DB
if (gadgets.size() == 0) {
// Load DB gadgets
if (gadgetSandbox) {
officialApps = dbApps;
}
for (GadgetSpec spec : officialApps.values()) {
GadgetSpec gadget = new GadgetSpec(spec.getAppId(),
spec.getName(), spec.getGadgetURL(),
spec.getChannels(), false, dataSource);
// only add ones that are visible in this context!
if (gadgetSandbox
|| gadget.show(viewerId, ownerId, pageName, dataSource)) {
String securityToken = socketSendReceive(viewerId, ownerId,
"" + gadget.getAppId());
gadgets.add(new PreparedGadget(gadget, this, moduleId++,
securityToken));
}
}
}
// sort the gadgets
Collections.sort(gadgets);
}
private String figureOwnerId(VitroRequest vreq) {
IndividualRequestAnalyzer requestAnalyzer = new IndividualRequestAnalyzer(vreq,
new IndividualRequestAnalysisContextImpl(vreq));
IndividualRequestInfo requestInfo = requestAnalyzer.analyze();
Individual owner = requestInfo.getIndividual();
return owner != null ? owner.getURI() : null;
}
private String getGadgetFileNameFromURL(String url) {
String[] urlbits = url.split("/");
return urlbits[urlbits.length - 1];
}
public boolean isDebug() {
return isDebug;
}
public boolean noCache() {
return noCache;
}
public String getOwnerId() {
return ownerId;
}
public boolean hasGadgetListeningTo(String channel) {
for (PreparedGadget gadget : getVisibleGadgets()) {
if (gadget.getGadgetSpec().listensTo(channel)) {
return true;
}
}
return false;
}
public static List<String> getOpenSocialId(List<Individual> individuals) {
List<String> personIds = new ArrayList<String>();
for (Individual ind : individuals) {
personIds.add(ind.getURI());
}
return personIds;
}
// JSON Helper Functions
public static String buildJSONPersonIds(List<String> personIds,
String message) throws JSONException {
JSONObject json = new JSONObject();
json.put("message", message);
json.put("personIds", personIds);
return json.toString();
}
public static String buildJSONPersonIds(String personId, String message) throws JSONException {
List<String> personIds = new ArrayList<String>();
personIds.add(personId);
return buildJSONPersonIds(personIds, message);
}
public static String buildJSONPersonIds(Individual ind, String message) throws JSONException {
List<String> personIds = new ArrayList<String>();
personIds.add(ind.getURI());
return buildJSONPersonIds(personIds, message);
}
/****
* public static String BuildJSONPubMedIds(Person person) { List<Int32>
* pubIds = new List<Int32>(); foreach (Publication pub in
* person.PublicationList) { foreach (PublicationSource pubSource in
* pub.PublicationSourceList) { if ("PubMed".Equals(pubSource.Name)) {
* pubIds.Add(Int32.Parse(pubSource.ID)); } } } Dictionary<string, Object>
* foundPubs = new Dictionary<string, object>(); foundPubs.Add("pubIds",
* pubIds); foundPubs.Add("message", "PubMedIDs for " +
* person.Name.FullName); JavaScriptSerializer serializer = new
* JavaScriptSerializer(); return serializer.Serialize(foundPubs); }
***/
public void setPubsubData(String key, String value) {
if (pubsubdata.containsKey(key)) {
pubsubdata.remove(key);
}
if (value != null && !value.isEmpty()) {
pubsubdata.put(key, value);
}
}
public Map<String, String> getPubsubData() {
return pubsubdata;
}
public void removePubsubGadgetsWithoutData() {
// if any visible gadgets depend on pubsub data that isn't present,
// throw them out
List<PreparedGadget> removedGadgets = new ArrayList<PreparedGadget>();
for (PreparedGadget gadget : gadgets) {
for (String channel : gadget.getGadgetSpec().getChannels()) {
if (!pubsubdata.containsKey(channel)) {
removedGadgets.add(gadget);
break;
}
}
}
for (PreparedGadget gadget : removedGadgets) {
gadgets.remove(gadget);
}
}
public void removeGadget(String name) {
// if any visible gadgets depend on pubsub data that isn't present,
// throw them out
PreparedGadget gadgetToRemove = null;
for (PreparedGadget gadget : gadgets) {
if (name.equals(gadget.getName())) {
gadgetToRemove = gadget;
break;
}
}
gadgets.remove(gadgetToRemove);
}
public String getPageName() {
return pageName;
}
public String getIdToUrlMapJavascript() {
String retval = "var idToUrlMap = {";
for (PreparedGadget gadget : gadgets) {
// retval += gadget.GetAppId() + ":'" + gadget.GetGadgetURL() +
// "', ";
retval += "'remote_iframe_" + gadget.getAppId() + "':'"
+ gadget.getGadgetURL() + "', ";
}
return retval.substring(0, retval.length() - 2) + "};";
}
public boolean isVisible() {
// always have turned on for ProfileDetails.aspx because we want to
// generate the "profile was viewed" in Javascript (bot proof)
// regardless of any gadgets being visible, and we need this to be True
// for the shindig javascript libraries to load
return (configuration.getProperty(SHINDIG_URL_PROP) != null
&& (getVisibleGadgets().size() > 0) || getPageName().equals(
"/display"));
}
public List<PreparedGadget> getVisibleGadgets() {
return gadgets;
}
public void postActivity(int userId, String title) throws SQLException {
postActivity(userId, title, null, null, null);
}
public void postActivity(int userId, String title, String body) throws SQLException {
postActivity(userId, title, body, null, null);
}
public void postActivity(int userId, String title, String body,
String xtraId1Type, String xtraId1Value) throws SQLException {
Connection conn = null;
Statement stmt = null;
String sqlCommand = "INSERT INTO shindig_activity (userId, activity, xtraId1Type, xtraId1Value) VALUES ('"
+ userId + "','<activity xmlns=\"http://ns.opensocial.org/2008/opensocial\"><postedTime>"
+ System.currentTimeMillis() + "</postedTime><title>" + title + "</title>"
+ (body != null ? "<body>" + body + "</body>" : "") + "</activity>','"
+ xtraId1Type + "','" + xtraId1Value + "');";
try {
conn = dataSource.getConnection();
stmt = conn.createStatement();
stmt.executeUpdate(sqlCommand);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String socketSendReceive(String viewer, String owner, String gadget)
throws IOException {
// These keys need to match what you see in
// edu.ucsf.orng.shindig.service.SecureTokenGeneratorService in
// Shindig
String[] tokenService = configuration.getProperty(
"OpenSocial.tokenService").split(":");
String request = "c=default" + (viewer != null ? "&v=" + URLEncoder.encode(viewer, "UTF-8") : "") +
(owner != null ? "&o=" + URLEncoder.encode(owner, "UTF-8") : "") + "&g=" + gadget + "\r\n";
// Create a socket connection with the specified server and port.
Socket s = new Socket(tokenService[0],
Integer.parseInt(tokenService[1]));
// Send request to the server.
s.getOutputStream().write(request.getBytes());
// Receive the encoded content.
int bytes = 0;
String page = "";
byte[] bytesReceived = new byte[256];
// The following will block until the page is transmitted.
while ((bytes = s.getInputStream().read(bytesReceived)) > 0) {
page += new String(bytesReceived, 0, bytes);
}
return page;
}
public String getContainerJavascriptSrc() {
return configuration.getProperty(SHINDIG_URL_PROP)
+ "/gadgets/js/core:dynamic-height:osapi:pubsub:rpc:views:shindig-container.js?c=1"
+ (isDebug ? "&debug=1" : "");
}
public String getGadgetJavascript() {
String lineSeparator = System.getProperty("line.separator");
String gadgetScriptText = lineSeparator
+ "var my = {};"
+ lineSeparator
+ "my.gadgetSpec = function(appId, name, url, secureToken, view, closed_width, open_width, start_closed, chrome_id, visible_scope) {"
+ lineSeparator + "this.appId = appId;" + lineSeparator
+ "this.name = name;" + lineSeparator + "this.url = url;"
+ lineSeparator + "this.secureToken = secureToken;"
+ lineSeparator + "this.view = view || 'default';"
+ lineSeparator + "this.closed_width = closed_width;"
+ lineSeparator + "this.open_width = open_width;"
+ lineSeparator + "this.start_closed = start_closed;"
+ lineSeparator + "this.chrome_id = chrome_id;" + lineSeparator
+ "this.visible_scope = visible_scope;" + lineSeparator + "};"
+ lineSeparator + "my.pubsubData = {};" + lineSeparator;
for (String key : getPubsubData().keySet()) {
gadgetScriptText += "my.pubsubData['" + key + "'] = '"
+ getPubsubData().get(key) + "';" + lineSeparator;
}
gadgetScriptText += "my.openSocialURL = '"
+ configuration.getProperty(SHINDIG_URL_PROP) + "';"
+ lineSeparator + "my.debug = " + (isDebug() ? "1" : "0") + ";"
+ lineSeparator + "my.noCache = " + (noCache() ? "1" : "0")
+ ";" + lineSeparator + "my.gadgets = [";
for (PreparedGadget gadget : getVisibleGadgets()) {
gadgetScriptText += "new my.gadgetSpec(" + gadget.getAppId() + ",'"
+ gadget.getName() + "','" + gadget.getGadgetURL() + "','"
+ gadget.getSecurityToken() + "','" + gadget.getView()
+ "'," + gadget.getClosedWidth() + ","
+ gadget.getOpenWidth() + ","
+ (gadget.getStartClosed() ? "1" : "0") + ",'"
+ gadget.getChromeId() + "','"
+ gadget.getGadgetSpec().getVisibleScope() + "'), ";
}
gadgetScriptText = gadgetScriptText.substring(0,
gadgetScriptText.length() - 2)
+ "];"
+ lineSeparator;
return gadgetScriptText;
}
}

View file

@ -0,0 +1,123 @@
package edu.ucsf.vitro.opensocial;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class PreparedGadget implements Comparable<PreparedGadget> {
private GadgetSpec gadgetSpec;
private OpenSocialManager helper;
private int moduleId;
private String securityToken;
public PreparedGadget(GadgetSpec gadgetSpec, OpenSocialManager helper,
int moduleId, String securityToken) {
this.gadgetSpec = gadgetSpec;
this.helper = helper;
this.moduleId = moduleId;
this.securityToken = securityToken;
}
public int compareTo(PreparedGadget other) {
GadgetViewRequirements gvr1 = this.getGadgetViewRequirements();
GadgetViewRequirements gvr2 = other.getGadgetViewRequirements();
return ("" + this.getView() + (gvr1 != null ? gvr1.getDisplayOrder()
: Integer.MAX_VALUE)).compareTo("" + other.getView()
+ (gvr2 != null ? gvr2.getDisplayOrder() : Integer.MAX_VALUE));
}
public GadgetSpec getGadgetSpec() {
return gadgetSpec;
}
public String getSecurityToken() {
return securityToken;
}
public int getAppId() {
return gadgetSpec.getAppId();
}
public String getName() {
return gadgetSpec.getName();
}
public int getModuleId() {
return moduleId;
}
public String getGadgetURL() {
return gadgetSpec.getGadgetURL();
}
GadgetViewRequirements getGadgetViewRequirements() {
return gadgetSpec.getGadgetViewRequirements(helper.getPageName());
}
public String getView() {
GadgetViewRequirements reqs = getGadgetViewRequirements();
if (reqs != null) {
return reqs.getView();
}
// default behavior that will get invoked when there is no reqs. Useful
// for sandbox gadgets
else if (helper.getPageName().equals("individual-EDIT-MODE")) {
return "home";
} else if (helper.getPageName().equals("individual")) {
return "profile";
} else if (helper.getPageName().equals("gadgetDetails")) {
return "canvas";
} else if (gadgetSpec.getGadgetURL().contains("Tool")) {
return "small";
} else {
return null;
}
}
public int getOpenWidth() {
GadgetViewRequirements reqs = getGadgetViewRequirements();
return reqs != null ? reqs.getOpenWidth() : 0;
}
public int getClosedWidth() {
GadgetViewRequirements reqs = getGadgetViewRequirements();
return reqs != null ? reqs.getClosedWidth() : 0;
}
public boolean getStartClosed() {
GadgetViewRequirements reqs = getGadgetViewRequirements();
// if the page specific reqs are present, honor those. Otherwise defaut
// to true for regular gadgets, false for sandbox gadgets
return reqs != null ? reqs.getStartClosed() : !gadgetSpec.fromSandbox();
}
public String getChromeId() {
GadgetViewRequirements reqs = getGadgetViewRequirements();
if (reqs != null) {
return reqs.getChromeId();
}
// default behavior that will get invoked when there is no reqs. Useful
// for sandbox gadgets
else if (gadgetSpec.getGadgetURL().contains("Tool")) {
return "gadgets-tools";
} else if (helper.getPageName().equals("individual-EDIT-MODE")) {
return "gadgets-edit";
} else if (helper.getPageName().equals("individual")) {
return "gadgets-view";
} else if (helper.getPageName().equals("gadgetDetails")) {
return "gadgets-detail";
} else if (helper.getPageName().equals("search")) {
return "gadgets-search";
} else {
return null;
}
}
public String getCanvasURL() throws UnsupportedEncodingException {
return "~/gadget?appId=" + getAppId() + "&Person="
+ URLEncoder.encode(helper.getOwnerId(), "UTF-8");
}
public String toString() {
return "" + this.moduleId + ", (" + this.gadgetSpec.toString() + ")";
}
}

View file

@ -0,0 +1,488 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.reasoner;
import org.apache.log4j.Level;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mindswap.pellet.jena.PelletReasonerFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
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 edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
public class SimpleReasonerPropertyTest extends AbstractTestClass {
long delay = 50;
@Before
public void suppressErrorOutput() {
suppressSyserr();
//Turn off log messages to console
setLoggerLevel(SimpleReasoner.class, Level.OFF);
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF);
}
/*
* basic scenarios around adding abox data
*
* Create a Tbox with property P inverseOf property Q.
* Pellet will compute TBox inferences. Add a statement
* a P b, and verify that b Q a is inferred.
* Add a statement c Q d and verify that d Q c
* is inferred.
*/
@Test
public void addABoxAssertion1() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
P.addInverseOf(Q);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register the SimpleReasoner listener with it
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// 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");
// b Q a is inferred from a P b
aBox.add(a,P,b);
Assert.assertTrue(inf.contains(b,Q,a));
// d P c is inferred from c Q d.
aBox.add(c,Q,d);
Assert.assertTrue(inf.contains(d,P,c));
}
/*
* don't infer if it's already in the abox
*/
@Test
public void addABoxAssertion2() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
P.addInverseOf(Q);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and add statement b Q a
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
// Individuals a, b, c and d
Resource a = aBox.createResource("http://test.vivo/a");
Resource b = aBox.createResource("http://test.vivo/b");
aBox.add(b,Q,a);
// register SimpleReasoner
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// b Q a is inferred from a P b, but it is already in the abox
aBox.add(a,P,b);
Assert.assertFalse(inf.contains(b,Q,a));
}
/*
* don't infer if it's already in the abox
*/
@Test
public void addABoxAssertion3() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
P.addInverseOf(Q);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register SimpleReasoner
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// Individuals a, b, c and d
Resource a = aBox.createResource("http://test.vivo/a");
Resource b = aBox.createResource("http://test.vivo/b");
// b Q a is inferred from a P b, but it is already in the abox
aBox.add(a,P,b);
aBox.add(b,Q,a);
Assert.assertFalse(inf.contains(b,Q,a));
}
/*
* adding abox data where the property has an inverse and
* and equivalent property.
*/
@Test
public void addABoxAssertion4() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty R = tBox.createOntProperty("http://test.vivo/R");
R.setLabel("property R", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
R.addEquivalentProperty(P);
P.addEquivalentProperty(R);
P.addInverseOf(Q);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register the SimpleReasoner listener with it
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// 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");
// b Q a is inferred from a R b.
aBox.add(a,R,b);
Assert.assertTrue(inf.contains(b,Q,a));
// d P c is inferred from c Q d.
aBox.add(c,Q,d);
Assert.assertTrue(inf.contains(d,P,c));
Assert.assertTrue(inf.contains(d,R,c));
}
/*
* basic scenarios around removing abox data
*/
@Test
public void removedABoxAssertion1() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
OntProperty T = tBox.createOntProperty("http://test.vivo/T");
Q.setLabel("property T", "en-US");
P.addInverseOf(Q);
P.addInverseOf(T);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register the SimpleReasoner listener with it
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// 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");
// b Q a is inferred from a P b.
aBox.add(a,P,b);
Assert.assertTrue(inf.contains(b,Q,a));
// d P c is inferred from c Q d and from c T d
aBox.add(c,Q,d);
aBox.add(c,T,d);
Assert.assertTrue(inf.contains(d,P,c));
aBox.remove(a,P,b);
Assert.assertFalse(inf.contains(b,Q,a));
aBox.remove(c,Q,d);
Assert.assertTrue(inf.contains(d,P,c));
}
/*
* removing abox data with equivalent and inverse properties
*/
@Test
public void removedABoxAssertion2() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
OntProperty T = tBox.createOntProperty("http://test.vivo/T");
Q.setLabel("property T", "en-US");
P.addInverseOf(Q);
Q.addInverseOf(P);
P.addEquivalentProperty(T);
T.addEquivalentProperty(P);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register the SimpleReasoner listener with it
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
// Individuals a, b, c and d
Resource a = aBox.createResource("http://test.vivo/a");
Resource b = aBox.createResource("http://test.vivo/b");
// b Q a is inferred from a P b and a T b.
aBox.add(a,P,b);
aBox.add(a,T,b);
Assert.assertTrue(inf.contains(b,Q,a));
Assert.assertFalse(inf.contains(a,P,b));
aBox.remove(a,P,b);
Assert.assertTrue(inf.contains(b,Q,a));
}
/*
* removing abox data with equivalent and inverse properties
*/
@Test
public void removedABoxAssertion3() {
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
P.addInverseOf(Q);
// this is the model to receive inferences
Model inf = ModelFactory.createDefaultModel();
// create an ABox and register the SimpleReasoner listener with it
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
Resource a = aBox.createResource("http://test.vivo/a");
Resource b = aBox.createResource("http://test.vivo/b");
aBox.add(a,P,b);
aBox.register(new SimpleReasoner(tBox, aBox, inf));
aBox.add(b,Q,a);
Assert.assertFalse(inf.contains(b,Q,a));
Assert.assertFalse(inf.contains(a,P,b));
aBox.remove(a,P,b);
Assert.assertTrue(inf.contains(a,P,b));
}
/*
* Basic scenario around adding an inverseOf assertion to the
* TBox
*/
@Test
public void addTBoxInverseAssertion1() throws InterruptedException {
// Create TBox, ABox and Inference models and register
// the ABox reasoner listeners with the ABox and TBox
// Pellet will compute TBox inferences
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
OntProperty P = tBox.createOntProperty("http://test.vivo/P");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/Q");
Q.setLabel("property Q", "en-US");
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
Model inf = ModelFactory.createDefaultModel();
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
aBox.register(simpleReasoner);
SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner);
tBox.register(simpleReasonerTBoxListener);
// 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");
// abox statements
aBox.add(a,P,b);
aBox.add(c,P,d);
aBox.add(b,Q,a);
// Assert P and Q as inverses and wait for SimpleReasoner TBox
// thread to end
Q.addInverseOf(P);
tBox.rebind();
tBox.prepare();
while (!VitroBackgroundThread.getLivingThreads().isEmpty()) {
Thread.sleep(delay);
}
// Verify inferences
Assert.assertTrue(inf.contains(d,Q,c));
Assert.assertFalse(inf.contains(b,Q,a));
simpleReasonerTBoxListener.setStopRequested();
}
/*
* Basic scenario around removing an inverseOf assertion to the
* TBox
*/
@Test
public void removeTBoxInverseAssertion1() throws InterruptedException {
// Create TBox, ABox and Inference models and register
// the ABox reasoner listeners with the ABox and TBox
// Pellet will compute TBox inferences
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
// set up TBox and Abox
OntProperty P = tBox.createOntProperty("http://test.vivo/propP");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/propQ");
Q.setLabel("property Q", "en-US");
Q.addInverseOf(P);
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
Model inf = ModelFactory.createDefaultModel();
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
aBox.register(simpleReasoner);
SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner);
tBox.register(simpleReasonerTBoxListener);
// Individuals a, b, c and d
Resource c = aBox.createResource("http://test.vivo/c");
Resource d = aBox.createResource("http://test.vivo/d");
// abox statements
aBox.add(c,P,d);
Assert.assertTrue(inf.contains(d,Q,c));
// Remove P and Q inverse relationship and wait for
// SimpleReasoner TBox thread to end.
Q.removeInverseProperty(P);
tBox.rebind();
tBox.prepare();
while (!VitroBackgroundThread.getLivingThreads().isEmpty()) {
Thread.sleep(delay);
}
// Verify inferences
Assert.assertFalse(inf.contains(d,Q,c));
simpleReasonerTBoxListener.setStopRequested();
}
/*
* Basic scenario around recomputing the ABox inferences
*/
@Test
public void recomputeABox1() throws InterruptedException {
// Create TBox, ABox and Inference models and register
// the ABox reasoner listeners with the ABox and TBox
// Pellet will compute TBox inferences
OntModel tBox = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
// set up TBox and Abox
OntProperty P = tBox.createOntProperty("http://test.vivo/propP");
P.setLabel("property P", "en-US");
OntProperty Q = tBox.createOntProperty("http://test.vivo/propQ");
Q.setLabel("property Q", "en-US");
Q.addInverseOf(P);
OntProperty X = tBox.createOntProperty("http://test.vivo/propX");
P.setLabel("property X", "en-US");
OntProperty Y = tBox.createOntProperty("http://test.vivo/propY");
Q.setLabel("property Y", "en-US");
X.addInverseOf(Y);
OntModel aBox = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
Model inf = ModelFactory.createDefaultModel();
SimpleReasoner simpleReasoner = new SimpleReasoner(tBox, aBox, inf);
aBox.register(simpleReasoner);
SimpleReasonerTBoxListener simpleReasonerTBoxListener = getTBoxListener(simpleReasoner);
tBox.register(simpleReasonerTBoxListener);
// 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");
// abox statements
aBox.add(a,P,b);
aBox.add(c,X,d);
simpleReasoner.recompute();
while (simpleReasoner.isRecomputing()) {
Thread.sleep(delay);
}
// Verify inferences
Assert.assertTrue(inf.contains(b,Q,a));
Assert.assertTrue(inf.contains(d,Y,c));
simpleReasonerTBoxListener.setStopRequested();
}
//==================================== Utility methods ====================
SimpleReasonerTBoxListener getTBoxListener(SimpleReasoner simpleReasoner) {
return new SimpleReasonerTBoxListener(simpleReasoner, new Exception().getStackTrace()[1].getMethodName());
}
// To help in debugging the unit test
void printModel(Model model, String modelName) {
System.out.println("\nThe " + modelName + " model has " + model.size() + " statements:");
System.out.println("---------------------------------------------------------------------");
model.write(System.out);
}
// To help in debugging the unit test
void printModel(OntModel ontModel, String modelName) {
System.out.println("\nThe " + modelName + " model has " + ontModel.size() + " statements:");
System.out.println("---------------------------------------------------------------------");
ontModel.writeAll(System.out,"N3",null);
}
}

View file

@ -26,6 +26,7 @@ public class DataPropertyDaoStub implements DataPropertyDao {
// ----------------------------------------------------------------------
private final Map<String, DataProperty> dpMap = new HashMap<String, DataProperty>();
private final Map<String, String> configFilesMap = new HashMap<String, String>();
public void addDataProperty(DataProperty dataProperty) {
if (dataProperty == null) {
@ -40,6 +41,18 @@ public class DataPropertyDaoStub implements DataPropertyDao {
dpMap.put(uri, dataProperty);
}
public void setCustomListViewConfigFileName(DataProperty property, String filename) {
if (property == null) {
throw new NullPointerException("property may not be null.");
}
String uri = property.getURI();
if (uri == null) {
throw new NullPointerException("uri may not be null.");
}
configFilesMap.put(uri, filename);
}
// ----------------------------------------------------------------------
// Stub methods
// ----------------------------------------------------------------------
@ -49,6 +62,17 @@ public class DataPropertyDaoStub implements DataPropertyDao {
return dpMap.get(dataPropertyURI);
}
@Override
public String getCustomListViewConfigFileName(DataProperty dataProperty) {
if (dataProperty == null) {
return null;
}
String uri = dataProperty.getURI();
if (uri == null) {
return null;
}
return configFilesMap.get(uri);
}
// ----------------------------------------------------------------------
// Un-implemented methods
// ----------------------------------------------------------------------

View file

@ -1,3 +1,5 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
import java.util.HashMap;

View file

@ -111,14 +111,6 @@
:configContextFor rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext .
:inheritingConfigContextFor rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext ;
rdfs:subPropertyOf :configContextFor .
:nonInheritingConfigContextFor rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext ;
rdfs:subPropertyOf :configContextFor .
:qualifiedBy rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext .
@ -130,6 +122,14 @@
rdfs:domain :ConfigContext ;
rdfs:subPropertyOf :qualifiedBy .
:inheritingConfigurationFor rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext ;
rdfs:subPropertyOf :configContextFor .
:nonInheritingConfigurationFor rdf:type owl:ObjectProperty ;
rdfs:domain :ConfigContext ;
rdfs:subPropertyOf :configContextFor .
:hasListView rdf:type owl:ObjectProperty ;
rdfs:range :ListDisplayView ;
rdfs:domain :PropertyDisplayConfig ;
@ -246,15 +246,15 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:defer rdf:type :OfferEditOption ,
owl:NamedIndividual .
owl:NamedIndividual .
:false rdf:type :OfferEditOption ,
owl:NamedIndividual .
:doNotOfferForEdit rdf:type :OfferEditOption ,
owl:NamedIndividual .
:ifStatement rdf:type :OfferEditOption ,
owl:NamedIndividual .
owl:NamedIndividual .
:true rdf:type :OfferEditOption ,
:offerForEdit rdf:type :OfferEditOption ,
owl:NamedIndividual .
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -112,7 +112,10 @@ owl:versionInfo
a owl:DatatypeProperty.
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#queryModel>
a owl:DatatypeProperty.
a owl:DatatypeProperty.
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
a owl:DatatypeProperty.
######### Object Properties#########
###Basic

View file

@ -786,38 +786,38 @@
</servlet-mapping>
<servlet>
<servlet-name>ObjectPropertyHierarchyListingController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.listing.ObjectPropertyHierarchyListingController</servlet-class>
<servlet-name>ShowObjectPropertyHierarchyController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ShowObjectPropertyHierarchyController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ObjectPropertyHierarchyListingController</servlet-name>
<servlet-name>ShowObjectPropertyHierarchyController</servlet-name>
<url-pattern>/showObjectPropertyHierarchy</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DataPropertyHierarchyListingController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.listing.DataPropertyHierarchyListingController</servlet-class>
<servlet-name>ShowDataPropertyHierarchyController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ShowDataPropertyHierarchyController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataPropertyHierarchyListingController</servlet-name>
<servlet-name>ShowDataPropertyHierarchyController</servlet-name>
<url-pattern>/showDataPropertyHierarchy</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PropertyWebappsListingController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.listing.PropertyWebappsListingController</servlet-class>
<servlet-name>ListPropertyWebappsController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListPropertyWebappsController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PropertyWebappsListingController</servlet-name>
<servlet-name>ListPropertyWebappsController</servlet-name>
<url-pattern>/listPropertyWebapps</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DatatypePropertiesListingController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.listing.DatatypePropertiesListingController</servlet-class>
<servlet-name>ListDatatypePropertiesController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListDatatypePropertiesController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DatatypePropertiesListingController</servlet-name>
<servlet-name>ListDatatypePropertiesController</servlet-name>
<url-pattern>/listDatatypeProperties</url-pattern>
</servlet-mapping>
@ -1300,6 +1300,20 @@
<url-pattern>/admin/getObjectClasses</url-pattern>
</servlet-mapping>
<!-- VIVO OpenSocial Extension by UCSF -->
<servlet>
<servlet-name>GadgetController</servlet-name>
<servlet-class>edu.ucsf.vitro.opensocial.GadgetController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GadgetController</servlet-name>
<url-pattern>/gadget</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GadgetController</servlet-name>
<url-pattern>/gadget/sandbox</url-pattern>
</servlet-mapping>
<!-- ==================== tag libraries ============================== -->
<jsp-config>
<taglib>

View file

@ -65,6 +65,11 @@ span#expandAll {
float: right;
font-size: 0.85em;
}
span.rangeClass {
color:#064D68;
padding-left:22px;
padding-right:8px;
}
div#expandLink {
margin-top:-10px;
width:100%;

View file

@ -1,3 +1,5 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
.menuFlag {
width:67px;
height:18px;

View file

@ -0,0 +1,26 @@
// Textarea and select clone() bug workaround | Spencer Tipping
// Licensed under the terms of the MIT source code license
// Motivation.
// jQuery's clone() method works in most cases, but it fails to copy the value of textareas and select elements. This patch replaces jQuery's clone() method with a wrapper that fills in the
// values after the fact.
// An interesting error case submitted by Piotr Przybył: If two <select> options had the same value, the clone() method would select the wrong one in the cloned box. The fix, suggested by Piotr
// and implemented here, is to use the selectedIndex property on the <select> box itself rather than relying on jQuery's value-based val().
(function (original) {
jQuery.fn.clone = function () {
var result = original.apply(this, arguments),
my_textareas = this.find('textarea').add(this.filter('textarea')),
result_textareas = result.find('textarea').add(this.filter('textarea')),
my_selects = this.find('select').add(this.filter('select')),
result_selects = result.find('select').add(this.filter('select'));
for (var i = 0, l = my_textareas.length; i < l; ++i) $(result_textareas[i]).val($(my_textareas[i]).val());
for (var i = 0, l = my_selects.length; i < l; ++i) result_selects[i].selectedIndex = my_selects[i].selectedIndex;
return result;
};
}) (jQuery.fn.clone);
// Generated by SDoc

View file

@ -1,18 +1,34 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var pageManagementUtils = {
dataGetterLabelToURI:null,//initialized by custom data
processDataGetterUtils:processDataGetterUtils,//an external class that should exist before this one
dataGetterMap:null,
// on initial page setup
onLoad:function(){
if (this.disableFormInUnsupportedBrowsers()) {
return;
}
this.mixIn();
this.initDataGetterProcessors(),
this.initObjects();
this.bindEventListeners();
this.initDisplay();
},
initDataGetterProcessors:function() {
//data getter processor map should come in from custom data
//Go through each and initialize with their class
if(pageManagementUtils.processDataGetterUtils != null) {
var dataGetterProcessorMap = pageManagementUtils.dataGetterProcessorMap = pageManagementUtils.processDataGetterUtils.dataGetterProcessorMap;
$.each(dataGetterProcessorMap, function(key, dataGetterProcessorObject) {
//passes class name from data getter label to uri to processor
dataGetterProcessorObject.initProcessor(pageManagementUtils.dataGetterLabelToURI[key]);
})
}
},
disableFormInUnsupportedBrowsers: function() {
var disableWrapper = $('#ie67DisableWrapper');
@ -28,6 +44,7 @@ var pageManagementUtils = {
},
mixIn: function() {
//Data getter process list input should be retrieved from the custom data
// Mix in the custom form utility methods
$.extend(this, vitro.customFormUtils);
// Get the custom form data from the page
@ -35,11 +52,12 @@ var pageManagementUtils = {
},
initObjects:function(){
this.counter = 0;
this.contentTypeSelect = $("#typeSelect");
this.contentTypeSelect = $("select#typeSelect");
//list of options
this.contentTypeSelectOptions = $('select#typeSelect option');
this.classGroupSection = $("section#classGroup");
this.nonClassGroupSection = $("section#nonClassGroup");
this.classGroupSection = $("section#browseClassGroup");
this.sparqlQuerySection = $("section#sparqlQuery");
this.fixedHTMLSection = $("section#fixedHtml");
//From original menu management edit
this.defaultTemplateRadio = $('input.default-template');
this.customTemplateRadio = $('input.custom-template');
@ -48,12 +66,19 @@ var pageManagementUtils = {
// this.changeContentType = $('#changeContentType');
this.selectContentType = $('#selectContentType');
// this.existingContentType = $('#existingContentType');
this.selectClassGroupDropdown = $('#selectClassGroup');
this.classesForClassGroup = $('#classesInSelectedGroup');
this.selectClassGroupDropdown = $('select#selectClassGroup');
this.classesForClassGroup = $('section#classesInSelectedGroup');
this.selectedGroupForPage = $('#selectedContentTypeValue');
this.allClassesSelectedCheckbox = $('#allSelected');
this.displayInternalMessage = $('#internal-class label em');
this.pageContentSubmissionInputs = $("#pageContentSubmissionInputs");
this.headerBar = $("section#headerBar");
this.moreContentButton = $("input#moreContent");
this.isMenuCheckbox = $("input#menuCheckbox");
this.menuSection = $("section#menu");
this.submitButton = $("input#submit");
this.leftSideDiv = $("div#leftSide");
this.rightSideDiv = $("div#rightSide")
},
initDisplay: function(){
//right side components
@ -62,125 +87,120 @@ var pageManagementUtils = {
//Why would you want to hide this? This hides everything
// $("section#pageDetails").hide();
$("section#headerBar").hide();
this.headerBar.hide();
this.classGroupSection.hide();
this.nonClassGroupSection.hide();
$("section#classesInSelectedGroup").addClass('hidden');
$("input#moreContent").hide();
this.sparqlQuerySection.hide();
this.fixedHTMLSection.hide();
this.classesForClassGroup.addClass('hidden');
this.moreContentButton.hide();
//left side components
$("input.default-template").attr('checked',true);
$("input#menuCheckbox").attr('checked',false);
$("section#menu").hide();
this.defaultTemplateRadio.attr('checked',true);
this.isMenuCheckbox.attr('checked',false);
this.menuSection.hide();
},
bindEventListeners:function(){
$("input.default-template").click( function() {
$("section#custom-template").addClass('hidden');
this.defaultTemplateRadio.click( function() {
pageManagementUtils.customTemplate.addClass('hidden');
//Also clear custom template value so as not to submit it
pageManagementUtils.clearInputs(pageManagementUtils.customTemplate);
});
$("input.custom-template").click( function() {
$("section#custom-template").removeClass('hidden');
this.customTemplateRadio.click( function() {
pageManagementUtils.customTemplate.removeClass('hidden');
});
$("input#menuCheckbox").click( function() {
if ( $("section#menu").is(':hidden') ) {
$("section#menu").show();
this.isMenuCheckbox.click( function() {
if ( pageManagementUtils.menuSection.is(':hidden') ) {
pageManagementUtils.menuSection.show();
}
else {
$("section#menu").hide();
pageManagementUtils.menuSection.hide();
}
});
$("input#submit").click( function() {
this.submitButton.click( function() {
$("section#pageDetails").show();
});
//Collapses the current content and creates a new section of content
//Resets the content to be cloned to default settings
$("input#moreContent").click( function() {
this.moreContentButton.click( function() {
var selectedType = pageManagementUtils.contentTypeSelect.val();
var selectedTypeText = $("#typeSelect option:selected").text();
//Not sure why selected group here? This won't always be true for more content
//var selectedGroup = $('select#selectClassGroup').val();
//Aren't these already hidden?
//Hide both sections
$("section#classGroup").hide();
$("section#nonClassGroup").hide();
//Reset class group
pageManagementUtils.resetClassGroupSection();
//Hide all sections
pageManagementUtils.classGroupSection.hide();
pageManagementUtils.fixedHTMLSection.hide();
pageManagementUtils.sparqlQuerySection.hide();
//Reset main content type drop-down
pageManagementUtils.contentTypeSelectOptions.eq(0).attr('selected', 'selected');
$("input#moreContent").hide();
if ( $("div#leftSide").css("height") != undefined ) {
$("div#leftSide").css("height","");
if ( $("div#leftSide").height() < $("div#rightSide").height() ) {
$("div#leftSide").css("height",$("div#rightSide").height() + "px");
pageManagementUtils.moreContentButton.hide();
if ( pageManagementUtils.leftSideDiv.css("height") != undefined ) {
pageManagementUtils.leftSideDiv.css("height","");
if ( pageManagementUtils.leftSideDiv.height() < pageManagementUtils.rightSideDiv.height() ) {
pageManagementUtils.leftSideDiv.css("height",pageManagementUtils.rightSideDiv.height() + "px");
}
}
$("section#headerBar").hide();
$("section#headerBar").text("");
//pageManagementUtils.cloneContentArea(selectedType,selectedGroup);
pageManagementUtils.cloneContentArea(selectedType, selectedTypeText);
pageManagementUtils.contentTypeSelect.focus();
pageManagementUtils.headerBar.hide();
pageManagementUtils.headerBar.text("");
pageManagementUtils.cloneContentArea(selectedType, selectedTypeText);
//Reset class group section AFTER cloning not before
pageManagementUtils.resetClassGroupSection();
//Clear all inputs values
pageManagementUtils.clearSourceTemplateValues();
pageManagementUtils.contentTypeSelect.focus();
});
//replacing with menu management edit version which is extended with some of the logic below
this.selectClassGroupDropdown.change(function() {
pageManagementUtils.chooseClassGroup();
});
/*
$("select#selectClassGroup").change( function() {
if ( $("select#selectClassGroup").val() == "" ) {
$("section#classesInSelectedGroup").addClass('hidden');
$("div#leftSide").css("height","");
$("input#moreContent").hide();
this.contentTypeSelect.change( function() {
_this = pageManagementUtils;
pageManagementUtils.clearSourceTemplateValues();
if ( _this.contentTypeSelect.val() == "browseClassGroup" ) {
pageManagementUtils.classGroupSection.show();
pageManagementUtils.fixedHTMLSection.hide();
pageManagementUtils.sparqlQuerySection.hide();
pageManagementUtils.moreContentButton.hide();
pageManagementUtils.headerBar.text("Browse Class Group - ");
pageManagementUtils.headerBar.show();
}
else {
$("section#classesInSelectedGroup").removeClass('hidden');
$("input#moreContent").show();
if ( $("div#leftSide").height() < $("div#rightSide").height() ) {
$("div#leftSide").css("height",$("div#rightSide").height() + "px");
}
}
});*/
$("select#typeSelect").change( function() {
$('input#variable').val("");
$('textarea#textArea').val("");
if ( $("#typeSelect").val() == "browseClassGroup" ) {
$("section#classGroup").show();
$("section#nonClassGroup").hide();
$("input#moreContent").hide();
$("section#headerBar").text("Browse Class Group - ");
$("section#headerBar").show();
}
if ( $("#typeSelect").val() == "fixedHtml" || $("#typeSelect").val() == "sparqlQuery" ) {
$("section#classGroup").hide();
if ( $("#typeSelect").val() == "fixedHtml" ) {
$('span#taSpan').text("Enter fixed HTML here");
$("section#headerBar").text("Fixed HTML - ");
if ( _this.contentTypeSelect.val() == "fixedHtml" || _this.contentTypeSelect.val() == "sparqlQuery" ) {
pageManagementUtils.classGroupSection.hide();
//if fixed html show that, otherwise show sparq
if ( _this.contentTypeSelect.val() == "fixedHtml" ) {
pageManagementUtils.headerBar.text("Fixed HTML - ");
pageManagementUtils.fixedHTMLSection.show();
pageManagementUtils.sparqlQuerySection.hide();
}
else {
$('span#taSpan').text("Enter SPARQL query here");
$("section#headerBar").text("SPARQL Query Results - ");
pageManagementUtils.headerBar.text("SPARQL Query Results - ");
pageManagementUtils.sparqlQuerySection.show();
pageManagementUtils.fixedHTMLSection.hide();
}
$("section#nonClassGroup").show();
$("section#headerBar").show();
$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
$("section#classesInSelectedGroup").addClass('hidden');
$("input#moreContent").show();
pageManagementUtils.headerBar.show();
//$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
pageManagementUtils.classesForClassGroup.addClass('hidden');
pageManagementUtils.moreContentButton.show();
}
if ( $("#typeSelect").val() == "" ) {
$("section#classGroup").hide();
$("section#nonClassGroup").hide();
$("input#moreContent").hide();
$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
$("section#classesInSelectedGroup").addClass('hidden');
$("section#headerBar").hide();
$("section#headerBar").text("");
if ( _this.contentTypeSelect.val() == "" ) {
pageManagementUtils.classGroupSection.hide();
pageManagementUtils.fixedHTMLSection.hide();
pageManagementUtils.sparqlQuerySection.hide();
pageManagementUtils.moreContentButton.hide();
//$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
pageManagementUtils.classesForClassGroup.addClass('hidden');
pageManagementUtils.headerBar.hide();
pageManagementUtils.headerBar.text("");
}
pageManagementUtils.adjustSaveButtonHeight();
});
@ -194,13 +214,17 @@ var pageManagementUtils = {
});*/
//Submission: validate as well as create appropriate hidden json inputs
$("form").submit(function () {
$("form").submit(function (event) {
var validationError = pageManagementUtils.validateMenuItemForm();
if (validationError == "") {
//Create the appropriate json objects
pageManagementUtils.createPageContentForSubmission();
//return true;
//For testing, not submitting anything
//event.preventDefault();
return true;
} else{
$('#error-alert').removeClass('hidden');
$('#error-alert p').html(validationError);
//TODO: Check why scrolling appears to be a problem
@ -209,69 +233,48 @@ var pageManagementUtils = {
}
});
},
//Clear values in content areas that are cloned to create the page content type specific sections
//i.e. reset sparql query/class group areas
//TODO: Check if reset is more what we need here?
clearSourceTemplateValues:function() {
//inputs, textareas
pageManagementUtils.clearInputs(pageManagementUtils.fixedHTMLSection);
pageManagementUtils.clearInputs(pageManagementUtils.sparqlQuerySection);
pageManagementUtils.clearInputs(pageManagementUtils.classGroupSection);
},
clearInputs:function($el) {
//jquery selector :input selects all input text area select and button elements
$el.find("input").val("");
$el.find("textarea").val("");
//resetting class group section as well so selection is reset if type changes
$el.find("select option:eq(0)").attr("selected", "selected");
},
//Clone content area
cloneContentArea: function(contentType, contentTypeLabel) {
var ctr = pageManagementUtils.counter;
var counter = pageManagementUtils.counter;
var varOrClas;
var varOrClass;
//Clone the object, renaming ids and copying text area values as well
$newContentObj = pageManagementUtils.createCloneObject(contentType, counter);
if ( contentType == "fixedHTML" || contentType == "sparqlQuery" ) {
var taValue = $('textarea#textArea').val();
alert("original text area value is " + taValue);
var $newContentObj = $('section#nonClassGroup').clone();
$newContentObj.addClass("pageContent");
varOrClass = $newContentObj.find('input').val();
$newContentObj.show();
//Save content type
$newContentObj.attr("contentType", contentType);
$newContentObj.attr("id", contentType + counter);
$newContentObj.find('input#variable').attr("id","variable" + counter);
$newContentObj.find('textarea#textArea').attr("id","textArea" + counter);
$newContentObj.find('label#variableLabel').attr("id","variableLabel" + counter);
$newContentObj.find('label#taLabel').attr("id","taLabel" + counter);
//Keep the name of the inputs the same
// $newContentObj.find('input#variable').attr("name","variable" + counter);
// $newContentObj.find('textarea#textArea').attr("name","textArea" + counter);
// There's a jquery bug when cloning textareas: the value doesn't
// get cloned. So
// copy the value "manually."
$newContentObj.find("textarea[name='textArea']").val(taValue);
}
if ( contentType == "sparqlQuery" || contentType == "fixedHtml") {
varOrClass = $newContentObj.find('input[name="saveToVar"]').val();
}
else if ( contentType == "browseClassGroup" ) {
var $newContentObj = $('section#classGroup').clone();
$newContentObj.addClass("pageContent");
$newContentObj.show();
$newContentObj.attr("contentType", contentType);
$newContentObj.attr("id", "classGroup" + counter);
$newContentObj.find('section#selectContentType').attr("id", "selectContentType" + counter);
$newContentObj.find('select#selectClassGroup').val(groupValue);
$newContentObj.find('select#selectClassGroup').attr("id","selectClassGroup" + counter);
$newContentObj.find('select#selectClassGroup' + counter).attr("name","selectClassGroup" + counter);
$newContentObj.find('section#classesInSelectedGroup').attr("id","classesInSelectedGroup" + counter);
$newContentObj.find('section#classesInSelectedGroup' + counter).removeClass('hidden');
$newContentObj.find('p#selectClassesMessage').attr("id","selectClassesMessage" + counter);
// Will need to uncomment this and find a way to apply the css style
// $newContentObj.find('section#internal-class').attr("id","internal-class" +
// counter);
$newContentObj.find("input[name='display-internalClass']").attr("name","display-internalClass" + counter);
$newContentObj.find('ul#selectedClasses').attr("id","selectedClasses" + counter);
$newContentObj.find('ul#selectedClasses' + counter).attr("name","selectedClasses" + counter);
$newContentObj.find('ul#selectedClasses' + counter).children("li").each( function(i,abc) {
var $theCheckbox = $(this).find('input');
$theCheckbox.attr("name", $theCheckbox.attr("name") + counter);
});
varOrClass = $newContentObj.find('select#selectClassGroup' + counter + ' option:selected').text();
$newContentObj.find('section#classesInSelectedGroup' + counter).removeClass('hidden');
varOrClass = $newContentObj.find('select#selectClassGroup' + counter + ' option:selected').text();
}
pageManagementUtils.createClonedContentContainer($newContentObj, counter, contentTypeLabel, varOrClass);
//previously increased by 10, just increasing by 1 here
pageManagementUtils.counter++;
},
createClonedContentContainer:function($newContentObj, counter, contentTypeLabel, varOrClass) {
//Create the container for the new content
$newDivContainer = $("<div></div>", {
id: "divContainer" + counter,
"class": "pageContentContainer",
@ -281,10 +284,20 @@ var pageManagementUtils = {
+ "' class='pageContentWrapper'><input id='remove" + counter
+ "' type='button' class='delete' value='Delete' class='deleteButton' /></div>"
});
var $clickableSpan = $newDivContainer.children('span#clickable' + counter);
//Hide inner div
var $innerDiv = $newDivContainer.children('div#innerContainer' + counter);
$innerDiv.hide();
//Expand/collapse toggle
//Bind event listers for the new content for display/removal etc.
pageManagementUtils.bindClonedContentContainerEvents($newDivContainer, counter);
//Append the new container to the section storing these containers
$newDivContainer.appendTo($('section#contentDivs'));
//place new content object
$newContentObj.prependTo($innerDiv);
},
bindClonedContentContainerEvents:function($newDivContainer, counter) {
var $clickableSpan = $newDivContainer.children('span#clickable' + counter);
var $innerDiv = $newDivContainer.children('div#innerContainer' + counter);
//Expand/collapse toggle
$clickableSpan.click(function() {
if ( $innerDiv.is(':visible') ) {
$innerDiv.slideUp(222);
@ -302,26 +315,20 @@ var pageManagementUtils = {
}
window.setTimeout('pageManagementUtils.adjustSaveButtonHeight()', 223);
});
//remove button
$newRemoveButton = $innerDiv.find('input#remove' + counter);
// this will have to disable submitted fields as well as hide them.
$newRemoveButton.click(function() {
$innerDiv.parent("div").css("display","none");
pageManagementUtils.adjustSaveButtonHeight();
});
$newDivContainer.appendTo($('section#contentDivs'));
$newContentObj.prependTo($innerDiv);
counter = counter + 10;
},
resetClassGroupSection:function() {
$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
$("section#classesInSelectedGroup").addClass('hidden');
},
//finalize later, but basically use same attribute across page content and use attribute instead of id
//Attribute would be what keeps track of content, so contentCounter or something like that
toggleArrow:function() {
//doing this in clear inputs instead which will be triggered
//every time content type is changed AS well as on more content button after
//original content is cloned and stored
//$('select#selectClassGroup option').eq(0).attr('selected', 'selected');
pageManagementUtils.classesForClassGroup.addClass('hidden');
},
//Adjust save button height
adjustSaveButtonHeight:function() {
@ -345,7 +352,6 @@ var pageManagementUtils = {
} else {
//update existing content type with correct class group name and hide class group select again
var _this = pageManagementUtils;
// pageManagementUtils.hideClassGroups();
pageManagementUtils.selectedGroupForPage.html(results.classGroupName);
@ -372,14 +378,14 @@ var pageManagementUtils = {
//From NEW code
if (pageManagementUtils.selectClassGroupDropdown.val() == "" ) {
$("section#classesInSelectedGroup").addClass('hidden');
pageManagementUtils.classesForClassGroup.addClass('hidden');
$("div#leftSide").css("height","");
$("input#moreContent").hide();
pageManagementUtils.moreContentButton.hide();
}
else {
$("section#classesInSelectedGroup").removeClass('hidden');
$("input#moreContent").show();
pageManagementUtils.classesForClassGroup.removeClass('hidden');
pageManagementUtils.moreContentButton.show();
if ( $("div#leftSide").height() < $("div#rightSide").height() ) {
$("div#leftSide").css("height",$("div#rightSide").height() + "px");
}
@ -390,39 +396,24 @@ var pageManagementUtils = {
});
},
/*
showClassGroups: function() { //User has clicked change content type
//Show the section with the class group dropdown
this.selectContentType.removeClass("hidden");
//Hide the "change content type" section which shows the selected class group
this.existingContentType.addClass("hidden");
//Hide the checkboxes for classes within the class group
this.classesForClassGroup.addClass("hidden");
},
hideClassGroups: function() { //User has selected class group/content type, page should show classes for class group and 'existing' type with change link
//Hide the class group dropdown
this.selectContentType.addClass("hidden");
//Show the "change content type" section which shows the selected class group
this.existingContentType.removeClass("hidden");
//Show the classes in the class group
this.classesForClassGroup.removeClass("hidden");
},*/
toggleClassSelection: function() {
// Check/unckeck all classes for selection
$('input:checkbox[name=allSelected]').click(function(){
if ( this.checked ) {
// if checked, select all the checkboxes
$('input:checkbox[name=classInClassGroup]').attr('checked','checked');
// if checked, select all the checkboxes for this particular section
$(this).closest("ul").find('input:checkbox[name=classInClassGroup]').attr('checked','checked');
//$('input:checkbox[name=classInClassGroup]').attr('checked','checked');
} else {
// if not checked, deselect all the checkboxes
$('input:checkbox[name=classInClassGroup]').removeAttr('checked');
$(this).closest("ul").find('input:checkbox[name=classInClassGroup]').removeAttr('checked');
// $('input:checkbox[name=classInClassGroup]').removeAttr('checked');
}
});
$('input:checkbox[name=classInClassGroup]').click(function(){
$('input:checkbox[name=allSelected]').removeAttr('checked');
$(this).closest(ul).find('input:checkbox[name=allSelected]').removeAttr('checked');
});
}, //This is SPECIFIC to VIVO so should be moved there
updateInternalClassMessage:function(classGroupName) { //User has changed content type
@ -482,29 +473,63 @@ var pageManagementUtils = {
//Create a new hidden input with a specific name and assign value per page content
pageManagementUtils.createPageContentInputForSubmission(jsonObjectString);
});
//in this case it's a sparql data getter, but what about the others
/*
var len = pageContentSections.length;
var i;
for(i = 0; i < len; i++) {
var pageContentSection = $(pageContentSections[i]);
var pageContentSectionId = pageContentSection.attr("id");
var jsonObject = pageManagementUtils.processPageContentSection(pageContentSection);
var jsonObjectString = JSON.stringify(jsonObject);
//Create a new hidden input with a specific name and assign value per page content
pageManagementUtils.createPageContentInputForSubmission(jsonObjectString);
}*/
},
createPageContentInputForSubmission: function(inputValue) {
$("<input type='hidden' name='pageContentUnit' value='" + inputValue + "'>").appendTo(pageManagementUtils.pageContentSubmissionInputs);
},
//returns a json object with the data getter information required
processPageContentSection:function(pageContentSection) {
var variableValue = pageContentSection.find("input[name='variable']").val();
var queryValue = pageContentSection.find("textarea[name='textArea']").val();
var returnObject = {saveToVar:variableValue, query:queryValue, dataGetterClass:pageManagementUtils.dataGetterLabelToURI["sparqlDataGetter"], queryModel:"vitro:contextDisplayModel"};
return returnObject;
//This processing should be specific to the type and so that content type's specific processor will
//return the json object required
if(pageManagementUtils.processDataGetterUtils != null) {
var dataGetterType = pageManagementUtils.processDataGetterUtils.selectDataGetterType(pageContentSection);
if(pageManagementUtils.dataGetterProcessorMap != null) {
var dataGetterProcessor = pageManagementUtils.dataGetterProcessorMap[dataGetterType];
//the content type specific processor will create the json object to be returned
var jsonObject = dataGetterProcessor.processPageContentSection(pageContentSection);
return jsonObject;
} else {
//ERROR handling
alert("An error has occurred and the map of processors for this content is missing. Please contact the administrator");
return null;
}
}
alert("An error has occurred and the code for processing this content is missing a component. Please contact the administrator.");
//Error handling here
return null;
},
//clones and returns cloned object for content type
createCloneObject:function(contentType, counter) {
var originalObjectPath = 'section#' + contentType;
var $newContentObj = $(originalObjectPath).clone();
$newContentObj.addClass("pageContent");
//Save content type
$newContentObj.attr("contentType", contentType);
//Set id for object
$newContentObj.attr("id", contentType + counter);
$newContentObj.show();
pageManagementUtils.renameIdsInClone($newContentObj, counter);
// pageManagementUtils.cloneTextAreaValues(originalObjectPath, $newContentObj);
return $newContentObj;
},
//This is specifically for cloning text area values
//May not need this if implementing the jquery fix
///would need a similar function for select as well
cloneTextAreaValues:function(originalAncestorPath, $newAncestorObject) {
$(originalAncestorPath + " textarea").each(function(index, el) {
var originalTextAreaValue = $(this).val();
var originalTextAreaName = $(this).attr("name");
$newAncestorObject.find("textarea[name='" + originalTextAreaName + "']").val(originalTextAreaValue);
});
},
//given an object and a counter, rename all the ids
renameIdsInClone:function($newContentObj, counter) {
$newContentObj.find("[id]").each(function(index, el) {
var originalId = $(this).attr("id");
var newId = originalId + counter;
$(this).attr("id", newId);
});
}
};

View file

@ -0,0 +1,21 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
//Process sparql data getter and provide a json object with the necessary information
//Depending on what is included here, a different type of data getter might be used
var processClassGroupDataGetterContent = {
dataGetterClass:null,
//can use this if expect to initialize from elsewhere
initProcessor:function(dataGetterClassInput) {
this.dataGetterClass = dataGetterClassInput;
},
//Do we need a separate content type for each of the others?
processPageContentSection:function(pageContentSection) {
//Will look at classes etc.
var classGroup = pageContentSection.find("select[name='selectClassGroup']").val();
//query model should also be an input, ensure class group URI is saved as URI and not string
var returnObject = {classGroup:classGroup, dataGetterClass:this.dataGetterClass};
return returnObject;
}
}

View file

@ -0,0 +1,29 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
//This class is responsible for the product-specific form processing/content selection that might be possible
//Overrides the usual behavior of selecting the specific JavaScript class needed to convert the form inputs
//into a JSON object for submission based on the page content type
//This will need to be overridden or extended, what have you.. in VIVO
var processDataGetterUtils = {
dataGetterProcessorMap:{"browseClassGroup": processClassGroupDataGetterContent,
"sparqlQuery": processSparqlDataGetterContent,
"fixedHtml":processFixedHTMLDataGetterContent,
"individualsForClasses":processIndividualsForClassesDataGetterContent},
selectDataGetterType:function(pageContentSection) {
var contentType = pageContentSection.attr("contentType");
//The form can provide "browse class group" as content type but need to check
//whether this is in fact individuals for classes instead
if(contentType == "browseClassGroup") {
//Is ALL NOT selected and there are other classes, pick one
//this SHOULD be an array
var allClassesSelected = pageContentSection.find("input[name='allSelected']:checked");
//If all NOT selected then need to pick a different content type
if(allClassesSelected.length == 0) {
contentType = "individualsForClasses";
}
}
return contentType;
}
};

View file

@ -0,0 +1,20 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
//Process sparql data getter and provide a json object with the necessary information
var processFixedHTMLDataGetterContent = {
dataGetterClass:null,
//can use this if expect to initialize from elsewhere
initProcessor:function(dataGetterClass) {
this.dataGetterClass =dataGetterClass;
},
//requires variable and text area
processPageContentSection:function(pageContentSection) {
var saveToVarValue = pageContentSection.find("input[name='saveToVar']").val();
var htmlValue = pageContentSection.find("textarea[name='htmlValue']").val();
//query model should also be an input
var returnObject = {saveToVar:saveToVarValue, htmlValue:htmlValue, dataGetterClass:this.dataGetterClass};
return returnObject;
}
}

View file

@ -0,0 +1,24 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var processIndividualsForClassesDataGetterContent = {
dataGetterClass:null,
//can use this if expect to initialize from elsewhere
initProcessor:function(dataGetterClassInput) {
this.dataGetterClass = dataGetterClassInput;
},
//Do we need a separate content type for each of the others?
processPageContentSection:function(pageContentSection) {
//Will look at classes etc.
var classGroup = pageContentSection.find("select[name='selectClassGroup']").val();
//query model should also be an input
//Get classes selected
var classesSelected = [];
pageContentSection.find("input[name='classInClassGroup']:checked").each(function(){
//Need to make sure that the class is also saved as a URI
classesSelected.push($(this).val());
});
var returnObject = {classGroup:classGroup, classesSelectedInClassGroup:classesSelected, dataGetterClass:this.dataGetterClass};
return returnObject;
}
}

View file

@ -0,0 +1,23 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
//Process sparql data getter and provide a json object with the necessary information
var processSparqlDataGetterContent = {
dataGetterClass:null,
//can use this if expect to initialize from elsewhere
initProcessor:function(dataGetterClass) {
this.dataGetterClass =dataGetterClass;
},
processPageContentSection:function(pageContentSection) {
var variableValue = pageContentSection.find("input[name='saveToVar']").val();
var queryValue = pageContentSection.find("textarea[name='query']").val();
var queryModel = pageContentSection.find("input[name='queryModel']").val();
//query model should also be an input
//set query model to query model here - vitro:contentDisplayModel
var returnObject = {saveToVar:variableValue, query:queryValue, dataGetterClass:this.dataGetterClass, queryModel:queryModel};
return returnObject;
}
};

View file

@ -0,0 +1,449 @@
/*
Profiles Shindig Helper functions for gadget-to-container commands
*/
// dummy function so google analytics does not break for institutions who do not use it
_gaq = {};
_gaq.push = function(data) { //
};
// pubsub
gadgets.pubsubrouter.init(function(id) {
return my.gadgets[shindig.container.gadgetService.getGadgetIdFromModuleId(id)].url;
}, {
onSubscribe: function(sender, channel) {
setTimeout("my.onSubscribe('" + sender + "', '" + channel + "')", 3000);
// return true to reject the request.
return false;
},
onUnsubscribe: function(sender, channel) {
//alert(sender + " unsubscribes from channel '" + channel + "'");
// return true to reject the request.
return false;
},
onPublish: function(sender, channel, message) {
// return true to reject the request.
// track with google analytics
if (sender != '..' ) {
var moduleId = shindig.container.gadgetService.getGadgetIdFromModuleId(sender);
}
if (channel == 'VISIBLE') {
var statusId = document.getElementById(sender + '_status');
if (statusId) {
// only act on these in HOME view since they are only meant to be seen when viewer=owner
if (my.gadgets[moduleId].view != 'home') {
return true;
}
if (message == 'Y') {
statusId.style.color = 'GREEN';
statusId.innerHTML = 'This section is VISIBLE';
if (my.gadgets[moduleId].visible_scope == 'U') {
statusId.innerHTML += ' to UCSF';
}
else {
statusId.innerHTML += ' to the public';
}
}
else {
statusId.style.color = '#CC0000';
statusId.innerHTML = 'This section is HIDDEN';
if (my.gadgets[moduleId].visible_scope == 'U') {
statusId.innerHTML += ' from UCSF';
}
else {
statusId.innerHTML += ' from the public';
}
}
}
}
else if (channel == 'added' && my.gadgets[moduleId].view == 'home') {
if (message == 'Y') {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'SHOW', 'profile_edit_view']);
osapi.activities.create(
{ 'userId': gadgets.util.getUrlParameters()['Person'],
'appId': my.gadgets[moduleId].appId,
'activity': {'postedTime': new Date().getTime(), 'title': 'added a gadget', 'body': 'added the ' + my.gadgets[moduleId].name + ' gadget to their profile' }
}).execute(function(response){});
}
else {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'HIDE', 'profile_edit_view']);
}
}
else if (channel == 'status') {
// message should be of the form 'COLOR:Message Content'
var statusId = document.getElementById(sender + '_status');
if (statusId) {
var messageSplit = message.split(':');
if (messageSplit.length == 2) {
statusId.style.color = messageSplit[0];
statusId.innerHTML = messageSplit[1];
}
else {
statusId.innerHTML = message;
}
}
}
else if (channel == 'analytics') {
// publish to google analytics
// message should be JSON encoding object with required action and optional label and value
// as documented here: http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html
// note that event category will be set to the gadget name automatically by this code
// Note: message will be already converted to an object
if (message.hasOwnProperty('value')) {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action, message.label, message.value]);
}
else if (message.hasOwnProperty('label')) {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action, message.label]);
}
else {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action]);
}
}
else if (channel == 'profile') {
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'go_to_profile', message]);
document.location.href = '/' + location.pathname.split('/')[1] + '/display/n' + message;
}
else if (channel == 'JSONPersonIds' || channel == 'JSONPubMedIds') {
// do nothing, no need to alert
}
else {
alert(sender + " publishes '" + message + "' to channel '" + channel + "'");
}
return false;
}
});
// helper functions
my.findGadgetsAttachingTo = function(chromeId) {
var retval = [];
for (var i = 0; i < my.gadgets.length; i++) {
if (my.gadgets[i].chrome_id == chromeId) {
retval[retval.length] = my.gadgets[i];
}
}
return retval;
};
my.removeGadgets = function(gadgetsToRemove) {
for (var i = 0; i < gadgetsToRemove.length; i++) {
for (var j = 0; j < my.gadgets.length; j++) {
if (gadgetsToRemove[i].url == my.gadgets[j].url) {
my.gadgets.splice(j, 1);
break;
}
}
}
};
my.onSubscribe = function(sender, channel) {
// lookup pubsub data based on channel and if a match is found, publish the data to that channel after a delay
if (my.pubsubData[channel]) {
gadgets.pubsubrouter.publish(channel, my.pubsubData[channel]);
}
else {
alert(sender + " subscribes to channel '" + channel + "'");
}
//PageMethods.onSubscribe(sender, channel, my.pubsubHint, my.CallSuccess, my.CallFailed);
};
my.removeParameterFromURL = function(url, parameter) {
var urlparts= url.split('?'); // prefer to use l.search if you have a location/link object
if (urlparts.length>=2) {
var prefix= encodeURIComponent(parameter)+'=';
var pars= urlparts[1].split(/[&;]/g);
for (var i= pars.length; i-->0;) //reverse iteration as may be destructive
if (pars[i].lastIndexOf(prefix, 0)!==-1) //idiom for string.startsWith
pars.splice(i, 1);
url= urlparts[0]+'?'+pars.join('&');
}
return url;
};
// publish the people
my.CallSuccess = function(result) {
gadgets.pubsubrouter.publish('person', result);
};
// alert message on some failure
my.CallFailed = function(error) {
alert(error.get_message());
};
my.requestGadgetMetaData = function(view, opt_callback) {
var request = {
context: {
country: "default",
language: "default",
view: view,
ignoreCache : my.noCache,
container: "default"
},
gadgets: []
};
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
// only add those with matching views
if (my.gadgets[moduleId].view == view) {
request.gadgets[request.gadgets.length] = {'url': my.gadgets[moduleId].url, 'moduleId': moduleId};
}
}
var makeRequestParams = {
"CONTENT_TYPE" : "JSON",
"METHOD" : "POST",
"POST_DATA" : gadgets.json.stringify(request)};
gadgets.io.makeNonProxiedRequest(my.openSocialURL + "/gadgets/metadata",
function(data) {
data = data.data;
if (opt_callback) {
opt_callback(data);
}
},
makeRequestParams,
"application/javascript"
);
};
my.renderableGadgets = [];
my.generateGadgets = function(metadata) {
// put them in moduleId order
for (var i = 0; i < metadata.gadgets.length; i++) {
var moduleId = metadata.gadgets[i].moduleId;
// Notes by Eric. Not sure if I should have to calculate this myself, but I will.
var height = metadata.gadgets[i].height;
var width = metadata.gadgets[i].width;
var viewPrefs = metadata.gadgets[i].views[my.gadgets[moduleId].view];
if (viewPrefs) {
height = viewPrefs.preferredHeight || height;
width = viewPrefs.preferredWidth || width;
}
my.renderableGadgets[moduleId] = shindig.container.createGadget({'specUrl': metadata.gadgets[i].url, 'secureToken': my.gadgets[moduleId].secureToken,
'title': metadata.gadgets[i].title, 'userPrefs': metadata.gadgets[i].userPrefs,
'height': height, 'width': width, 'debug': my.debug});
// set the metadata for easy access
my.renderableGadgets[moduleId].setMetadata(metadata.gadgets[i]);
}
// this will be called multiple times, only render when all gadgets have been processed
var ready = my.renderableGadgets.length == my.gadgets.length;
for (var i = 0; ready && i < my.renderableGadgets.length; i++) {
if (!my.renderableGadgets[i]) {
ready = false;
}
}
if (ready) {
shindig.container.addGadgets(my.renderableGadgets );
shindig.container.renderGadgets();
}
};
my.init = function() {
// overwrite this RPC function. Do it at this level so that rpc.f (this.f) is accessible for getting module ID
// gadgets.rpc.register('requestNavigateTo', doProfilesNavigation);
shindig.container.gadgetClass = ProfilesGadget;
shindig.container.layoutManager = new ProfilesLayoutManager();
shindig.container.setNoCache(my.noCache);
shindig.container.gadgetService = new ProfilesGadgetService();
// since we render multiple views, we need to do somethign fancy by swapping out this value in getIframeUrl
shindig.container.setView('REPLACE_THIS_VIEW');
// do multiple times as needed if we have multiple views
// find out what views are being used and call requestGadgetMetaData for each one
var views = {};
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
var view = my.gadgets[moduleId].view;
if (!views[view]) {
views[view] = view;
my.requestGadgetMetaData(view, my.generateGadgets);
}
}
};
// ProfilesGadgetService
ProfilesGadgetService = function() {
shindig.IfrGadgetService.call(this);
};
ProfilesGadgetService.inherits(shindig.IfrGadgetService);
ProfilesGadgetService.prototype.requestNavigateTo = function(view, opt_params) {
var urlTemplate = gadgets.config.get('views')[view].urlTemplate;
var url = urlTemplate || 'OpenSocial.aspx?';
url += window.location.search.substring(1);
// remove appId if present
url = my.removeParameterFromURL(url, 'appId');
// Add appId if the URL Template begins with the word 'gadget'
if (urlTemplate.toLowerCase().indexOf('gadget') == 0) {
var moduleId = shindig.container.gadgetService.getGadgetIdFromModuleId(this.f);
var appId = my.gadgets[moduleId].appId;
url += (url.indexOf('?') != url.length - 1 ? '&' : '') + 'appId=' + appId;
}
if (opt_params) {
var paramStr = gadgets.json.stringify(opt_params);
if (paramStr.length > 0) {
url += (url.indexOf('?') != url.length - 1 ? '&' : '') + 'appParams=' + encodeURIComponent(paramStr);
}
}
if (url && document.location.href.indexOf(url) == -1) {
document.location.href = url;
}
};
// ProfilesGadget
ProfilesGadget = function(opt_params) {
shindig.Gadget.call(this, opt_params);
this.debug = my.debug;
this.serverBase_ = my.openSocialURL + "/gadgets/";
var gadget = this;
var subClass = shindig.IfrGadget;
this.metadata = {};
for (var name in subClass) if (subClass.hasOwnProperty(name)) {
if (name == 'getIframeUrl') {
// we need to keep this old one
gadget['originalGetIframeUrl'] = subClass[name];
}
else if (name != 'finishRender') {
gadget[name] = subClass[name];
}
}
};
ProfilesGadget.inherits(shindig.BaseIfrGadget);
ProfilesGadget.prototype.setMetadata = function(metadata) {
this.metadata = metadata;
};
ProfilesGadget.prototype.hasFeature = function(feature) {
for (var i = 0; i < this.metadata.features.length; i++) {
if (this.metadata.features[i] == feature) {
return true;
}
}
return false;
};
ProfilesGadget.prototype.getAdditionalParams = function() {
var params = '';
for (var key in my.gadgets[this.id].additionalParams) {
params += '&' + key + '=' + my.gadgets[this.id].additionalParams[key];
}
return params;
};
ProfilesGadget.prototype.finishRender = function(chrome) {
window.frames[this.getIframeId()].location = this.getIframeUrl();
if (my.gadgets[this.id].start_closed) {
this.handleToggle();
}
else if (chrome) {
// set the gadget box width, and remember that we always render as open
chrome.style.width = (my.gadgets[this.id].open_width || 600) + 'px';
}
};
ProfilesGadget.prototype.getIframeUrl = function() {
var url = this.originalGetIframeUrl();
return url.replace('REPLACE_THIS_VIEW', my.gadgets[this.id].view);
};
ProfilesGadget.prototype.handleToggle = function() {
var gadgetIframe = document.getElementById(this.getIframeId());
if (gadgetIframe) {
var gadgetContent = gadgetIframe.parentNode;
var gadgetImg = document.getElementById('gadgets-gadget-title-image-' + this.id);
if (gadgetContent.style.display) {
//OPEN
gadgetContent.parentNode.style.width = (my.gadgets[this.id].open_width || 600) + 'px';
gadgetContent.style.display = '';
gadgetImg.src = '/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareDownArrow.gif';
// refresh if certain features require so
//if (this.hasFeature('dynamic-height')) {
if (my.gadgets[this.id].chrome_id == 'gadgets-search') {
this.refresh();
document.getElementById(this.getIframeId()).contentWindow.location.reload(true);
}
if (my.gadgets[this.id].view == 'home') {
// record in google analytics
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'OPEN_IN_EDIT', 'profile_edit_view']);
}
else {
osapi.activities.create(
{ 'userId': gadgets.util.getUrlParameters()['Person'],
'appId': my.gadgets[this.id].appId,
'activity': {'postedTime': new Date().getTime(), 'title': 'gadget viewed', 'body': my.gadgets[this.id].name + ' gadget was viewed' }
}).execute(function(response){});
// record in google analytics
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'OPEN']);
}
}
else {
//CLOSE
gadgetContent.parentNode.style.width = (my.gadgets[this.id].closed_width || 600) + 'px';
gadgetContent.style.display = 'none';
gadgetImg.src = '/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareArrow.gif';
if (my.gadgets[this.id].view == 'home') {
// record in google analytics
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'CLOSE_IN_EDIT', 'profile_edit_view']);
}
else {
// record in google analytics
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'CLOSE']);
}
}
}
};
ProfilesGadget.prototype.getTitleBarContent = function(continuation) {
if (my.gadgets[this.id].view == 'canvas') {
document.getElementById("gadgets-title").innerHTML = (this.title ? this.title : 'Gadget');
continuation('<span class="gadgets-gadget-canvas-title"></span>');
}
else {
continuation(
'<div id="' + this.cssClassTitleBar + '-' + this.id +
'" class="' + this.cssClassTitleBar + '"><span class="' +
this.cssClassTitleButtonBar + '">' +
'<a href="#" onclick="shindig.container.getGadget(' + this.id +
').handleToggle();return false;" class="' + this.cssClassTitleButton +
'"><img id="gadgets-gadget-title-image-' + this.id + '" src="/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareDownArrow.gif"/></a></span> <span id="' +
this.getIframeId() + '_title" class="' + this.cssClassTitle + '">' +
'<a href="#" onclick="shindig.container.getGadget(' + this.id + ').handleToggle();return false;">' +
(this.title ? this.title : 'Gadget') + '</a>' + '</span><span id="' +
this.getIframeId() + '_status" class="gadgets-gadget-status"></span></div>');
}
};
// ProfilesLayoutManager. Creates a FloatLeftLayoutManager for every chromeId in our gadgets
ProfilesLayoutManager = function() {
shindig.LayoutManager.call(this);
// find out what chromeId's are being used, create a FloatLeftLayoutManager for each
this.layoutManagers = {};
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
var chromeId = my.gadgets[moduleId].chrome_id;
if (!this.layoutManagers[chromeId]) {
this.layoutManagers[chromeId] = new shindig.FloatLeftLayoutManager(chromeId);
}
}
};
ProfilesLayoutManager.inherits(shindig.LayoutManager);
ProfilesLayoutManager.prototype.getGadgetChrome = function(gadget) {
return this.layoutManagers[my.gadgets[gadget.id].chrome_id].getGadgetChrome(gadget);
};

View file

@ -32,6 +32,7 @@
this.form = $('form#classHierarchyForm');
this.select = $('select#displayOption');
this.addClass = $('input#addClass');
this.addGroup = $('input#addGroup');
},
bindEventListeners: function() {
@ -49,6 +50,10 @@
classHierarchyUtils.form.attr("action", "vclass_retry");
classHierarchyUtils.form.submit();
});
this.addGroup.click(function() {
classHierarchyUtils.form.attr("action", "editForm?controller=Classgroup");
classHierarchyUtils.form.submit();
});
},
buildClassHierarchyHtml: function() {
@ -96,6 +101,7 @@
getTheChildren: function(node) {
var childDetails = "";
var subclassString = " ";
var ctr = 0
$.each(node.children, function() {
if ( ctr == 0 ) {
@ -105,12 +111,18 @@
else {
childDetails += "<tr><td></td>" ;
}
if ( this.children.length == 1 ) {
subclassString += "<span style='font-size:0.8em'> (1 subclass)</span>";
}
else if ( this.children.length > 1 ) {
subclassString += "<span style='font-size:0.8em'> (" + this.children.length + " subclasses)</span>";
}
childDetails += "<td class='subclassCell'><span class='subclassExpandPlus' id='subclassExpand"
+ classHierarchyUtils.expandCounter + "'>&nbsp;</span>"
+ this.name + "</td></tr><tr><td></td><td><table id='subclassTable"
+ this.name + subclassString + "</td></tr><tr><td></td><td><table id='subclassTable"
+ classHierarchyUtils.expandCounter + "' class='subclassTable'>";
subclassString = " ";
classHierarchyUtils.clickableSpans.push('subclassExpand' + classHierarchyUtils.expandCounter);
classHierarchyUtils.expandCounter += 1;
@ -141,13 +153,13 @@
$clickableHeader.click(function() {
if ( $clickableHeader.attr('view') == "less" ) {
$clickableHeader.addClass("headerSpanMinus");
$('table#classHierarchy' + ctr).find('span').addClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('span.subclassExpandPlus').addClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('table.subclassTable').show();
$clickableHeader.attr('view', 'more' );
}
else {
$clickableHeader.removeClass("headerSpanMinus");
$('table#classHierarchy' + ctr).find('span').removeClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('span.subclassExpandPlus').removeClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('table.subclassTable').hide();
$clickableHeader.attr('view', 'less' );
}
@ -180,14 +192,14 @@
if ( classHierarchyUtils.expandAll.text() == "expand all" ) {
classHierarchyUtils.expandAll.text("collapse all");
$('span.headerSpanPlus').addClass("headerSpanMinus");
$('table.classHierarchy').find('span').addClass("subclassExpandMinus");
$('table.classHierarchy').find('span.subclassExpandPlus').addClass("subclassExpandMinus");
$('table.classHierarchy').find('table.subclassTable').show();
$('section#container').find('span.headerSpanPlus').attr('view','more');
}
else {
classHierarchyUtils.expandAll.text("expand all");
$('span.headerSpanPlus').removeClass("headerSpanMinus");
$('table.classHierarchy').find('span').removeClass("subclassExpandMinus");
$('table.classHierarchy').find('span.subclassExpandPlus').removeClass("subclassExpandMinus");
$('table.classHierarchy').find('table.subclassTable').hide();
$('section#container').find('span.headerSpanPlus').attr('view','less');
}

View file

@ -0,0 +1,293 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var objectPropHierarchyUtils = {
onLoad: function(urlBase,displayOption,type) {
this.imagePath = urlBase + "/images/";
this.propType = type;
this.initObjects();
this.expandAll.hide();
this.checkJsonTree();
if ( noProps ) {
this.buildNoPropsHtml();
}
else if ( displayOption == "all" ) {
this.buildAllPropsHtml();
}
else {
this.buildPropertyHierarchyHtml();
this.wireExpandLink();
}
if ( displayOption == "hierarchy" ) {
this.expandAll.show();
}
this.bindEventListeners();
},
initObjects: function() {
this.expandAll = $('span#expandAll').find('a');
this.classCounter = 1;
this.expandCounter = 1;
this.classHtml = "";
this.clickableSpans = [] ;
this.form = $('form#classHierarchyForm');
this.select = $('select#displayOption');
this.addProperty = $('input#addProperty');
noProps = new Boolean;
},
bindEventListeners: function() {
if ( this.propType == "object" ) {
this.select.change(function() {
if ( objectPropHierarchyUtils.select.val() == "all") {
objectPropHierarchyUtils.form.attr("action", "listPropertyWebapps");
}
else {
objectPropHierarchyUtils.form.attr("action", "showObjectPropertyHierarchy");
}
objectPropHierarchyUtils.form.submit();
});
this.addProperty.click(function() {
objectPropHierarchyUtils.form.attr("action", "editForm?controller=Property");
objectPropHierarchyUtils.form.submit();
});
}
else {
this.select.change(function() {
if ( objectPropHierarchyUtils.select.val() == "all") {
objectPropHierarchyUtils.form.attr("action", "listDatatypeProperties");
}
else {
objectPropHierarchyUtils.form.attr("action", "showDataPropertyHierarchy");
}
objectPropHierarchyUtils.form.submit();
});
this.addProperty.click(function() {
objectPropHierarchyUtils.form.attr("action", "editForm?controller=Dataprop");
objectPropHierarchyUtils.form.submit();
});
}
},
checkJsonTree: function() {
if ( json.length == 1 ) {
$.each(json, function() {
// check to see whether we have a 'no properties' message or an actual json tree
if ( this.name.indexOf("properties") != -1 && this.data == undefined ) {
noProps = true;
}
else {
noProps = false;
}
});
}
else {
noProps = false;
}
},
buildPropertyHierarchyHtml: function() {
$.each(json, function() {
$newClassSection = jQuery("<section></section>", {
id: "classContainer" + objectPropHierarchyUtils.classCounter
});
var descendants = "";
var headerSpan = "";
if ( this.children.length ) {
descendants = objectPropHierarchyUtils.getTheChildren(this);
headerSpan = "<span class='headerSpanPlus' id='headerSpan" + objectPropHierarchyUtils.classCounter
+ "' view='less'>&nbsp;</span>";
}
objectPropHierarchyUtils.classHtml += "<div>" + this.name + headerSpan + "</div>" + "<table class='classHierarchy' id='classHierarchy"
+ objectPropHierarchyUtils.classCounter + "'>" ;
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Local Name:</td><td>"
+ (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Group:</td><td>"
+ (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Domain Class:</td><td>"
+ (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " ";
objectPropHierarchyUtils.classHtml += "<span class='rangeClass'>Range Class:</span>"
+ (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += descendants;
objectPropHierarchyUtils.classHtml += "</table>";
// alert(objectPropHierarchyUtils.classHtml);
$newClassSection.html(objectPropHierarchyUtils.classHtml);
$newClassSection.appendTo($('section#container'));
objectPropHierarchyUtils.makeHeaderSpansClickable(objectPropHierarchyUtils.classCounter);
objectPropHierarchyUtils.makeSubpropertySpansClickable();
objectPropHierarchyUtils.clickableSpans = [] ;
objectPropHierarchyUtils.classHtml = "";
objectPropHierarchyUtils.classCounter += 1;
});
},
getTheChildren: function(node) {
var childDetails = "";
var subclassString = " ";
var ctr = 0
$.each(node.children, function() {
if ( ctr == 0 ) {
childDetails += "<tr><td class='classDetail'>Subproperties:</td>";
ctr = ctr + 1;
}
else {
childDetails += "<tr><td></td>" ;
}
if ( this.children.length == 1 ) {
subclassString += "<span style='font-size:0.8em'> (1 subclass)</span>";
}
else if ( this.children.length > 1 ) {
subclassString += "<span style='font-size:0.8em'> (" + this.children.length + " subclasses)</span>";
}
childDetails += "<td class='subclassCell' colspan='2'><span class='subclassExpandPlus' id='subclassExpand"
+ objectPropHierarchyUtils.expandCounter + "'>&nbsp;</span>"
+ this.name + subclassString + "</td></tr><tr><td></td><td colspan='2'><table id='subclassTable"
+ objectPropHierarchyUtils.expandCounter + "' class='subclassTable'>";
subclassString = " ";
objectPropHierarchyUtils.clickableSpans.push('subclassExpand' + objectPropHierarchyUtils.expandCounter);
objectPropHierarchyUtils.expandCounter += 1;
childDetails += "<tr><td class='classDetail'>Local Name:</td><td>"
+ (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "</td></tr>";
childDetails += "<tr><td class='classDetail'>Group:</td><td>"
+ (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "</td></tr>";
childDetails += "<tr><td class='classDetail'>Domain Class:</td><td>"
+ (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " ";
childDetails += "<span class='rangeClass'>Range Class:</span>"
+ (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "</td></tr>";
if ( this.children ) {
var grandChildren = objectPropHierarchyUtils.getTheChildren(this);
childDetails += grandChildren;
}
});
childDetails += "</table></td></tr>";
return childDetails;
},
makeHeaderSpansClickable: function(ctr) {
var $clickableHeader = $('section#classContainer' + ctr).find('span.headerSpanPlus');
$clickableHeader.click(function() {
if ( $clickableHeader.attr('view') == "less" ) {
$clickableHeader.addClass("headerSpanMinus");
$('table#classHierarchy' + ctr).find('span.subclassExpandPlus').addClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('table.subclassTable').show();
$clickableHeader.attr('view', 'more' );
}
else {
$clickableHeader.removeClass("headerSpanMinus");
$('table#classHierarchy' + ctr).find('span.subclassExpandPlus').removeClass("subclassExpandMinus");
$('table#classHierarchy' + ctr).find('table.subclassTable').hide();
$clickableHeader.attr('view', 'less' );
}
});
},// $('myOjbect').css('background-image', 'url(' + imageUrl + ')');
makeSubpropertySpansClickable: function() {
$.each(objectPropHierarchyUtils.clickableSpans, function() {
var currentSpan = this;
var $clickableSpan = $('section#container').find('span#' + currentSpan);
var $subclassTable = $('section#container').find('table#subclassTable' + currentSpan.replace("subclassExpand",""));
$clickableSpan.click(function() {
if ( $subclassTable.is(':visible') ) {
$subclassTable.hide();
$subclassTable.find('table.subclassTable').hide();
$subclassTable.find('span').removeClass("subclassExpandMinus");
$clickableSpan.removeClass("subclassExpandMinus");
}
else {
$subclassTable.show();
$clickableSpan.addClass("subclassExpandMinus");
}
});
});
},
wireExpandLink: function() {
this.expandAll.click(function() {
if ( objectPropHierarchyUtils.expandAll.text() == "expand all" ) {
objectPropHierarchyUtils.expandAll.text("collapse all");
$('span.headerSpanPlus').addClass("headerSpanMinus");
$('table.classHierarchy').find('span.subclassExpandPlus').addClass("subclassExpandMinus");
$('table.classHierarchy').find('table.subclassTable').show();
$('section#container').find('span.headerSpanPlus').attr('view','more');
}
else {
objectPropHierarchyUtils.expandAll.text("expand all");
$('span.headerSpanPlus').removeClass("headerSpanMinus");
$('table.classHierarchy').find('span.subclassExpandPlus').removeClass("subclassExpandMinus");
$('table.classHierarchy').find('table.subclassTable').hide();
$('section#container').find('span.headerSpanPlus').attr('view','less');
}
});
},
buildAllPropsHtml: function() {
$.each(json, function() {
$newClassSection = jQuery("<section></section>", {
id: "classContainer" + objectPropHierarchyUtils.classCounter
});
objectPropHierarchyUtils.classHtml += "<div>" + this.name + "</div>" + "<table class='classHierarchy' id='classHierarchy"
+ objectPropHierarchyUtils.classCounter + "'>" ;
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Local Name:</td><td>"
+ (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Group:</td><td>"
+ (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += "<tr><td class='classDetail'>Domain Class:</td><td>"
+ (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " ";
objectPropHierarchyUtils.classHtml += "<span class='rangeClass'>Range Class:</span>"
+ (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "</td></tr>";
objectPropHierarchyUtils.classHtml += "</table>";
$newClassSection.html(objectPropHierarchyUtils.classHtml);
$newClassSection.appendTo($('section#container'));
objectPropHierarchyUtils.classHtml = "";
objectPropHierarchyUtils.classCounter += 1;
});
},
buildNoPropsHtml: function() {
$.each(json, function() {
$newClassSection = jQuery("<section></section>", {
id: "classContainer" + objectPropHierarchyUtils.classCounter
});
objectPropHierarchyUtils.classHtml = "<h4>" + this.name + "</h4>";
$newClassSection.html(objectPropHierarchyUtils.classHtml);
$newClassSection.appendTo($('section#container'));
objectPropHierarchyUtils.classHtml = "";
});
}
}

View file

@ -1,16 +1,16 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<%@ taglib prefix="form" uri="http://vitro.mannlib.cornell.edu/edit/tags" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%-- colspan set to 4 in DatapropRetryController.java --%>
<tr class="editformcell">
<td valign="top" colspan="1">
<b>Public Name</b><br/><i>as will display on public pages</i><br/>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%-- colspan set to 4 in DatapropRetryController.java --%>
<tr class="editformcell">
<td valign="top" colspan="1">
<b>Public Name</b><br/><i>as will display on public pages</i><br/>
<input name="PublicName" value="<form:value name="PublicName"/>"/>
<c:set var="PublicNameError"><form:error name="PublicName"/></c:set>
<c:if test="${!empty PublicNameError}">
<span class="notice"><c:out value="${PublicNameError}"/></span>
</c:if>
</c:if>
</td>
<td valign="top" colspan="1">
<b>Property Group</b><br/>
@ -27,10 +27,10 @@
<b>Update Level</b><br /><i>(specify least restrictive level allowed)</i><br />
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"><form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/></select>
</td>
</tr>
</tr>
<tr class="editformcell">
<!-- c:set var="existingLocalName" value="<form:value name='LocalName'/>"/ -->
<td valign="top" colspan="2">
<!-- c:set var="existingLocalName" value="<form:value name='LocalName'/>"/ -->
<td valign="top" colspan="2">
<b>Ontology</b><br/>
<c:choose>
<c:when test="${_action eq 'update'}">
@ -45,42 +45,42 @@
<form:option name="Namespace"/>
</select>
</c:otherwise>
</c:choose>
</td>
<td valign="top" colspan="2">
</c:choose>
</td>
<td valign="top" colspan="2">
<b>Local Name*</b>
<c:choose>
<c:when test="${_action eq 'update'}">
<br/><i>Change only via the "change URI" button on the previous screen</i><br/>
<br/><i>Change only via the "change URI" button on the previous screen</i><br/>
<input name="LocalName" value="<form:value name="LocalName"/>" disabled="disabled"/>
</c:when>
<c:otherwise>
<i>(must be a valid XML name)<br/>startLowercaseAndUseCamelStyle</i><br/>
<input name="LocalName" value="<form:value name="LocalName"/>"/>
</c:otherwise>
</c:choose>
</c:choose>
<c:set var="LocalNameError"><form:error name="LocalName"/></c:set>
<c:if test="${!empty LocalNameError}">
<span class="notice"><c:out value="${LocalNameError}"/></span>
</c:if>
</c:if>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Domain Class</b><br/>
<select name="DomainClassURI">
<form:option name="DomainClassURI"/>
</select>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Range Datatype</b><br/>
<select name="RangeDatatypeURI">
<form:option name="RangeDatatypeURI"/>
</select>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Domain Class</b><br/>
<select name="DomainClassURI">
<form:option name="DomainClassURI"/>
</select>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="2">
<b>Range Datatype</b><br/>
<select name="RangeDatatypeURI">
<form:option name="RangeDatatypeURI"/>
</select>
</td>
<td valign="bottom" colspan="2">
<c:set var="functionalLabel" value="<b>Functional property</b> <i>(has at most one value for each individual)</i>" />
@ -92,7 +92,7 @@
<input name="Functional" type="checkbox" value="TRUE"/>${functionalLabel}
</c:otherwise>
</c:choose>
</td>
</td>
</tr>
<tr class="editformcell">
@ -104,17 +104,17 @@
<span class="notice"><c:out value="${ExampleError}"/></span>
</c:if>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="4">
<b>Description</b> for ontology editors<br/>
</tr>
<tr class="editformcell">
<td valign="top" colspan="4">
<b>Description</b> for ontology editors<br/>
<textarea name="Description"><form:value name="Description"/></textarea>
<c:set var="DescriptionError"><form:error name="Description"/></c:set>
<c:if test="${!empty DescriptionError}">
<span class="notice"><c:out value="${DescriptionError}"/></span>
</c:if>
</td>
</c:if>
</td>
</tr>
<tr class="editformcell">
@ -126,24 +126,24 @@
<span class="notice"><c:out value="${PublicDescriptionError}"/></span>
</c:if>
</td>
</tr>
<tr class="editformcell">
<td valign="top" colspan="1">
<b>Display Tier</b><br/>
</tr>
<tr class="editformcell">
<td valign="top" colspan="1">
<b>Display Tier</b><br/>
<input name="DisplayTier" value="<form:value name="DisplayTier"/>"/>
<c:set var="DisplayTierError"><form:error name="DisplayTier"/></c:set>
<c:if test="${!empty DisplayTierError}">
<span class="notice"><c:out value="${DisplayTierError}"/></span>
</c:if>
</td>
<td valign="top" colspan="1">
<b>Display Limit</b><br/>
</c:if>
</td>
<td valign="top" colspan="1">
<b>Data Entry Limit</b><br/>
<input name="DisplayLimit" value="<form:value name="DisplayLimit"/>"/>
<c:set var="DisplayLimitError"><form:error name="DisplayLimit"/></c:set>
<c:if test="${!empty DisplayLimitError}">
<span class="notice"><c:out value="${DisplayLimitError}"/></span>
</c:if>
</c:if>
</td>
<td valign="top" colspan="1">
<em>Optional: <b>custom entry form</b></em><br />
@ -155,4 +155,4 @@
</td>
</td>
</tr>

View file

@ -0,0 +1,15 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Save to variable indicated in generator -->
<#assign htmlExists = false/>
<#if variableName?has_content>
<#assign htmlExists = true />
</#if>
<#if htmlExists>
${.globals[variableName]}
<#else>
No HTML specified.
</#if>

View file

@ -6,6 +6,7 @@
<#assign subjectUri = individual.controlPanelUrl()?split("=") >
<#list propertyGroups.all as group>
<#assign groupName = group.getName(nameForOtherGroup)>
<#assign verbose = (verbosePropertySwitch.currentValue)!false>
<section class="property-group" role="region">
<nav class="scroll-up" role="navigation">
@ -29,13 +30,13 @@
<#-- Property display name -->
<#if property.localName == "authorInAuthorship" >
<h3 id="${property.localName}">${property.name} <@p.addLink property editable /> <@p.verboseDisplay property />
<a id="managePropLink" href="${urls.base}/managePublications?subjectUri=${subjectUri[1]!}" title="manage publications" <#if verbosePropertySwitch.currentValue>style="padding-top:10px"</#if> >
<a id="managePropLink" href="${urls.base}/managePublications?subjectUri=${subjectUri[1]!}" title="manage publications" <#if verbose>style="padding-top:10px"</#if> >
manage publications
</a>
</h3>
<#elseif property.localName == "hasResearcherRole">
<h3 id="${property.localName}">${property.name} <@p.addLink property editable /> <@p.verboseDisplay property />
<a id="managePropLink" href="${urls.base}/manageGrants?subjectUri=${subjectUri[1]!}" title="manage grants & projects" <#if verbosePropertySwitch.currentValue>style="padding-top:10px"</#if> >
<a id="managePropLink" href="${urls.base}/manageGrants?subjectUri=${subjectUri[1]!}" title="manage grants & projects" <#if verbose>style="padding-top:10px"</#if> >
manage grants & projects
</a>
</h3>

View file

@ -48,6 +48,30 @@
</#list>
</ul>
<#-- VIVO OpenSocial Extension by UCSF -->
<#if openSocial??>
<#if openSocial.visible>
<script type="text/javascript" language="javascript">
// find the 'Search' gadget(s).
var searchGadgets = my.findGadgetsAttachingTo("gadgets-search");
var keyword = '${querytext}';
// add params to these gadgets
if (keyword) {
for (var i = 0; i < searchGadgets.length; i++) {
var searchGadget = searchGadgets[i];
searchGadget.additionalParams = searchGadget.additionalParams || {};
searchGadget.additionalParams["keyword"] = keyword;
}
}
else { // remove these gadgets
my.removeGadgets(searchGadgets);
}
</script>
<div id="gadgets-search" class="gadgets-gadget-parent"></div>
</#if>
</#if>
<#-- Paging controls -->
<#if (pagingLinks?size > 0)>
<div class="searchpages">

View file

@ -16,6 +16,9 @@
<option value="group" <#if displayOption == "group">selected</#if> >Classes by Class Group</option>
</select>
<input id="addClass" value="Add New Class" class="form-button" type="submit" />
<#if displayOption == "group">
<input type="submit" id="addGroup" class="form-button" value="Add New Group"/>
</#if>
</form>

View file

@ -0,0 +1,49 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--
Used to display both the object and data property hierarchies, though there are
separate controllers for those. Also used to display lists of "all" object and
data properties, though there are separate controllers for those, too.
-->
<section role="region">
<h2>${pageTitle!}</h2>
<#if !displayOption?has_content>
<#assign displayOption = "hierarchy">
</#if>
<form name="classHierarchyForm" id="classHierarchyForm" action="show<#if propertyType == "object">Object<#else>Data</#if>PropertyHierarchy" method="post" role="classHierarchy">
<label id="displayOptionLabel" class="inline">Display Options</label>
<select id="displayOption" name="displayOption">
<option value="hierarchy" <#if displayOption == "asserted">selected</#if> >Property Hierarchy</option>
<option value="all" <#if displayOption == "all">selected</#if> >All Properties</option>
</select>
<input type="submit" class="form-button" id="addProperty" value="Add new <#if propertyType == "object">object<#else>data</#if> property"/>
</form>
<div id="expandLink"><span id="expandAll" ><a href="#" title="expand all">expand all</a></span></div>
<section id="container">
</section>
</section>
<script language="javascript" type="text/javascript" >
var json = [${jsonTree!}];
</script>
<script language="javascript" type="text/javascript" >
$(document).ready(function() {
objectPropHierarchyUtils.onLoad("${urls.base!}","${displayOption!}","${propertyType}");
});
</script>
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/classHierarchy.css" />')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/siteAdmin/objectPropertyHierarchyUtils.js"></script>')}

View file

@ -0,0 +1,66 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Browse Class Groups Section-->
<#-----------Variable assignment-------------->
<#--Requires Menu action be defined in parent template-->
<#assign classGroup = pageData.classGroup />
<#assign classGroups = pageData.classGroups />
<#assign isClassGroupPage = false/>
<#assign includeAllClasses = false/>
<#-- some additional processing here which shows or hides the class group selection and classes based on initial action-->
<#assign existingClassGroupStyle = " " />
<#assign selectClassGroupStyle = 'class="hidden"' />
<#-- Reveal the class group and hide the class selects if adding a new menu item or editing an existing menu item with an empty class group (no classes)-->
<#-- Menu action needs to be sent from main template-->
<#if menuAction == "Add" || !classGroup?has_content>
<#assign existingClassGroupStyle = 'class="hidden"' />
<#assign selectClassGroupStyle = " " />
</#if>
<#--HTML Portion-->
<section id="browseClassGroup" style="background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-width:1px;border-style:solid;border-color:#ccc;">
<section id="selectContentType" name="selectContentType" ${selectClassGroupStyle} role="region">
<label for="selectClassGroup">Class Group<span class="requiredHint"> *</span></label>
<select name="selectClassGroup" id="selectClassGroup" role="combobox">
<option value="-1" role="option">Select one</option>
<#list classGroups as aClassGroup>
<option value="${aClassGroup.URI}" <#if aClassGroup.URI = associatedPageURI>selected</#if> role="option">${aClassGroup.publicName}</option>
</#list>
</select>
</section>
<section id="classesInSelectedGroup" name="classesInSelectedGroup" ${existingClassGroupStyle}>
<#-- Select classes in a class group -->
<p id="selectClassesMessage" name="selectClassesMessage">Select content to display<span class="requiredHint"> *</span></p>
<#include "pageManagement--classIntersections.ftl">
<ul id="selectedClasses" name="selectedClasses" role="menu">
<#--Adding a default class for "ALL" in case all classes selected-->
<li class="ui-state-default" role="menuitem">
<input type="checkbox" name="allSelected" id="allSelected" value="all" <#if !isIndividualsForClassesPage?has_content>checked</#if> />
<label class="inline" for="All"> All</label>
</li>
<#list classGroup as classInClassGroup>
<li class="ui-state-default" role="menuitem">
<input type="checkbox" id="classInClassGroup" name="classInClassGroup" value="${classInClassGroup.URI}"
<#if includeAllClasses = true>checked</#if>
<#if isIndividualsForClassesPage?has_content>
<#list includeClasses as includeClass>
<#if includeClass = classInClassGroup.URI>
checked
</#if>
</#list>
</#if> />
<label class="inline" for="${classInClassGroup.name}"> ${classInClassGroup.name}</label>
<span class="ui-icon-sortable"></span>
</li>
</#list>
</ul>
</section>
</section>
<#--Include JavaScript specific to the types of data getters related to this content-->
<#include "pageManagement--browseClassGroupsScripts.ftl">

View file

@ -0,0 +1,4 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Scripts for class group browsing -->
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/processClassGroupDataGetterContent.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/processIndividualsForClassesDataGetterContent.js"></script>')}

View file

@ -0,0 +1,5 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--These are the different content templates that will be cloned and used within page management-->
<#include "pageManagement--browseClassGroups.ftl">
<#include "pageManagement--sparqlQuery.ftl">
<#include "pageManagement--fixedHtml.ftl">

View file

@ -0,0 +1,16 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Sets up script for custom form data. Including here instead of as separate javascript
file to ensure this script is always loaded first. Can also make sure placed first in
scripts list.-->
<script type="text/javascript">
var customFormData = {
dataGetterLabelToURI:{
//maps labels to URIs
"browseClassGroup": "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData",
"individualsForClasses": "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter",
"sparqlQuery":"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter",
"fixedHtml":"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter"
}
};
</script>

View file

@ -0,0 +1,10 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--This contains the template for the fixed HTML content type that is to be cloned and used in page management-->
<section id="fixedHtml" style="background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-width:1px;border-style:solid;border-color:#ccc;">
<label id="fixedHTMLVariableLabel" for="fixedHTMLVariable">Variable Name<span class="requiredHint"> *</span></label>
<input type="text" name="saveToVar" size="20" value="" id="fixedHTMLSaveToVar" role="input" />
<label id="fixedHTMLValueLabel" for="fixedHTMLValue">Enter fixed HTML here<span id="fixedHTMLValueSpan"></span><span class="requiredHint"> *</span></label>
<textarea id="fixedHTMLValue" name="htmlValue" cols="70" rows="15" style="margin-bottom:7px"></textarea>
</section>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/processFixedHTMLDataGetterContent.js"></script>')}

View file

@ -0,0 +1,11 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--This contains the template for the Sparql Query content type that is to be cloned and used in page management-->
<section id="sparqlQuery" style="background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-width:1px;border-style:solid;border-color:#ccc;">
<label id="variableLabel" for="variable">Variable Name<span class="requiredHint"> *</span></label>
<input type="text" name="saveToVar" size="20" value="" id="saveToVar" role="input" />
<label id="queryModelLabel" for="queryModel">Query Model</label>
<input type="text" name="queryModel" size="20" value="" id="queryModel" role="input" />
<label id="queryLabel" for="queryLabel"><span id="querySpan">Enter SPARQL query here</span><span class="requiredHint"> *</span></label>
<textarea id="query" name="query" cols="70" rows="15" style="margin-bottom:7px"></textarea>
</section>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/processSparqlDataGetterContent.js"></script>')}

View file

@ -1,27 +1,16 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#--Set up variables-->
<#--------Set up variables-------->
<#assign pageData = editConfiguration.pageData />
<#assign menuAction = pageData.menuAction />
<#assign classGroup = pageData.classGroup />
<#assign classGroups = pageData.classGroups />
<#assign pageName = "" />
<#assign selectedTemplateType = "default" />
<#assign prettyUrl = ""/>
<#assign associatedPage = ""/>
<#assign associatedPageURI = ""/>
<#assign menuItem = ""/>
<#assign isClassGroupPage = false/>
<#assign includeAllClasses = false/>
<#-- some additional processing here which shows or hides the class group selection and classes based on initial action-->
<#assign existingClassGroupStyle = " " />
<#assign selectClassGroupStyle = 'class="hidden"' />
<#-- Reveal the class group and hide the class selects if adding a new menu item or editing an existing menu item with an empty class group (no classes)-->
<#if menuAction == "Add" || !classGroup?has_content>
<#assign existingClassGroupStyle = 'class="hidden"' />
<#assign selectClassGroupStyle = " " />
</#if>
<#------------HTML Portion------------->
<section id="error-alert" role="alert" class="hidden">
<img src="${urls.images}/iconAlert.png" width="24" height="24" alert="Error alert icon" />
<p></p>
@ -35,6 +24,7 @@
<input type="hidden" id="editKey" name="editKey" value="${editKey}" />
<input type="hidden" id="menuItem" name="menuItem" value="${menuItem}"/>
<h2>Add Page</h2>
<!--Drop down for the types of content possible-->
<section id="floatRight" style="margin-top:0px;float:right;background-color:#fff;width:580px;margin-right:-4px">
<div id="rightSide">
<section id="addPageOne" role="region">
@ -51,60 +41,14 @@
<section id="headerBar" style="background-color:#f5f5f5;border-color:#ccc;border-width:1px;border-style:solid;border-bottom-width:0px;padding-left:6px">
</section>
<section id="classGroup" style="background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-width:1px;border-style:solid;border-color:#ccc;">
<section id="selectContentType" name="selectContentType" ${selectClassGroupStyle} role="region">
<label for="selectClassGroup">Class Group<span class="requiredHint"> *</span></label>
<select name="selectClassGroup" id="selectClassGroup" role="combobox">
<option value="-1" role="option">Select one</option>
<#list classGroups as aClassGroup>
<option value="${aClassGroup.URI}" <#if aClassGroup.URI = associatedPageURI>selected</#if> role="option">${aClassGroup.publicName}</option>
</#list>
</select>
</section>
<section id="classesInSelectedGroup" name="classesInSelectedGroup" ${existingClassGroupStyle}>
<#-- Select classes in a class group -->
<p id="selectClassesMessage" name="selectClassesMessage">Select content to display<span class="requiredHint"> *</span></p>
<#include "pageManagement--classIntersections.ftl">
<ul id="selectedClasses" name="selectedClasses" role="menu">
<#--Adding a default class for "ALL" in case all classes selected-->
<li class="ui-state-default" role="menuitem">
<input type="checkbox" name="allSelected" id="allSelected" value="all" <#if !isIndividualsForClassesPage?has_content>checked</#if> />
<label class="inline" for="All"> All</label>
</li>
<#list classGroup as classInClassGroup>
<li class="ui-state-default" role="menuitem">
<input type="checkbox" id="classInClassGroup" name="classInClassGroup" value="${classInClassGroup.URI}"
<#if includeAllClasses = true>checked</#if>
<#if isIndividualsForClassesPage?has_content>
<#list includeClasses as includeClass>
<#if includeClass = classInClassGroup.URI>
checked
</#if>
</#list>
</#if> />
<label class="inline" for="${classInClassGroup.name}"> ${classInClassGroup.name}</label>
<#-- PLACEHOLDER - not yet implemented) -->
<span class="ui-icon-sortable"></span> <#--sortable icon for dragging and dropping menu items-->
</li>
</#list>
</ul>
</section>
</section>
<section id="nonClassGroup" style="background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-width:1px;border-style:solid;border-color:#ccc;">
<label id="variableLabel" for="variable">Variable Name<span class="requiredHint"> *</span></label>
<input type="text" name="variable" size="20" value="" id="variable" role="input" />
<label id="taLabel" for="selectClassGroup"><span id="taSpan"></span><span class="requiredHint"> *</span></label>
<textarea id="textArea" name="textArea" cols="70" rows="15" style="margin-bottom:7px"></textarea>
</section>
<#--This include file contains links to the templates that will be cloned and used for the different content types-->
<!--This content will be copied/shown for these particular content types, so any fields for n3 editing need to be included
here that correspond to a specific content type. These are related to specific "data getters" on the server side. -->
<#include "pageManagement--contentTemplates.ftl">
<input type="button" id="moreContent" name="moreContent" value="Add More Content" class="delete" style="margin-top:8px" />
</div>
</section>
<!--Information for page or menu item level-->
<div id="leftSide">
<section id="addPageOne" role="region" style="background-color:#fff;">
<label for="page-name">Title<span class="requiredHint"> *</span></label>
@ -137,35 +81,30 @@
<br />
<p class="requiredHint">* required fields</p>
</section>
<!--Hidden input with JSON objects added will be included here-->
<!--Hidden input with JSON objects added will be included here. This is the field with the page content information
mirroring what is required by the Data getter server side objects. -->
<div id="pageContentSubmissionInputs" style="display:none"></div>
</form>
</section>
<!-
<!--Hardcoding for now but should be retrieved from generator-->
<script type="text/javascript">
var customFormData = {
dataGetterLabelToURI:{
//maps labels to URIs
"browseClassGroup": "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData",
"sparqlDataGetter":"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter"
},
dataGetterMap:{"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData": "Class Group Page",
"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.BrowseDataGetter": "Browse Page",
"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter": "Class Group Page - Selected Classes",
"java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter": "Sparql Query Results" }
};
</script>
<!--Hardcoding for now but should be retrieved from generator: Custom data-->
<#include "pageManagement--customDataScript.ftl">
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')}
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/menupage/menuManagement.css" />')}
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/menupage/pageManagement.css" />')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery.fix.clone.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/json2.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>')}
${scripts.add('<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>')}
<#--Process Data Getter Utils will refer to the various content type specific javascript files that should
already have been added within the template section for each content type-->
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/processDataGetterUtils.js"></script>')}
<#--Page management is used on page load and utilizes processDataGetterUtils as well as the custom data from the custom data script-->
${scripts.add('<script type="text/javascript" src="${urls.base}/js/menupage/pageManagementUtils.js"></script>')}

View file

@ -34,9 +34,9 @@
</#if>
</#macro>
<#macro dataPropertyList property editable>
<#macro dataPropertyList property editable template=property.template>
<#list property.statements as statement>
<@propertyListItem property statement editable >${statement.value}</@propertyListItem>
<@propertyListItem property statement editable ><#include "${template}"></@propertyListItem>
</#list>
</#macro>