Merging with issue-vivo-101-sparqlupdate. Using develop licenser files that were in conflict. VIVO-255 VIVO-101

This commit is contained in:
Brian Caruso 2013-08-28 11:37:50 -04:00
commit 4c42128993
41 changed files with 1606 additions and 414 deletions

View file

@ -191,6 +191,7 @@
<!-- Copy the build.properties file to the resources directory. -->
<copy todir="${main.resources.dir}" file="${build.properties.file}" />
<!-- copy any xml files from source tree to the war directory -->
<copy todir="${main.compiled.dir}">
<fileset dir="${appbase.dir}/src" includes="**/*.xml" />

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -15,3 +15,13 @@ rdf:type
"true"^^xsd:boolean ;
display:requiresAction
a owl:ObjectProperty ;
rdfs:label "Required Action"@en-US ;
rdfs:comment "Indicates that a resource has a required action that may need to be authorized" .
rdfs:range display:RequiredAction .
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#offerCreateNewOptionAnnot>
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#selectFromExistingAnnot>
"true"^^xsd:boolean ;

View file

@ -4,59 +4,65 @@
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> .
#########Classes#########
###Basic
owl:Class
a owl:Class .
owl:Ontology
a owl:Class .
owl:AnnotationProperty
a owl:Class .
owl:DatatypeProperty
a owl:Class .
owl:ObjectProperty
a owl:Class .
owl:Class a owl:Class .
owl:Ontology a owl:Class .
owl:AnnotationProperty a owl:Class .
owl:DatatypeProperty a owl:
owl:ObjectProperty a owl:Class .
###Display Model
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#MainMenu>
display:MainMenu
a owl:Class ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#customDisplayViewAnnot>
"individual-menu.ftl"^^xsd:string .
vitro:customDisplayViewAnnot "individual-menu.ftl"^^xsd:string .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#NavigationElement>
a owl:Class .
display:NavigationElement a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page>
a owl:Class .
display:Page a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#HomePage>
a owl:Class .
display:HomePage a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#ClassGroupPage>
a owl:Class .
display:ClassGroupPage a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#IndividualsForClassesPage>
a owl:Class .
display:IndividualsForClassesPage a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#InternalClassesPage>
a owl:Class .
display:InternalClassesPage a owl:Class .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#DataGetter>
a owl:Class .
display:DataGetter a owl:Class .
display:RequiredAction a owl:Class ;
rdfs:comment "Represents a action that may need authorization to perform.".
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>
a owl:Class .
a owl:Class ;
rdfs:comment "Data getter for running a SPARQL query."
##Adding a data getter type that is Solr Class search, i.e. get individuals for VClass
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SolrIndividualsDataGetter>
a owl:Class .
a owl:Class ;
rdfs:comment "A data getter for a Solr Class search, i.e. get individuals for VClass" .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlUpdate>
a owl:Class ;
rdfs:comment "A data getter that runs a SPARQL Update" .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.BrowseDataGetter>
a owl:Class ;
rdfs:comment "A data getter for a standard Vitro browse page" .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData>
a owl:Class ;
rdfs:comment "A data getter for a VClassGroup page".
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter>
a owl:Class ;
rdfs:comment "A data getter for a Fixed piece of HTML stored in RDF".
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter>
a owl:Class .
########Data Properties#########
@ -64,67 +70,64 @@ owl:ObjectProperty
rdfs:comment
a owl:DatatypeProperty .
rdfs:label
a owl:DatatypeProperty .
owl:versionInfo
a owl:DatatypeProperty .
###Vitro model
###Vitro model
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#modTime>
vitro:modTime
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#displayRank>
vitro:displayRank
a owl:DatatypeProperty .
vitro:customDisplayViewAnnot
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#customDisplayViewAnnot>
a owl:DatatypeProperty .
###Display model
###Display model
display:listViewConfigFile
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#listViewConfigFile>
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
a owl:DatatypeProperty .
display:title
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
a owl:DatatypeProperty .
display:urlMapping
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#requiresBodyTemplate>
a owl:DatatypeProperty .
display:requiresBodyTemplate
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#isSelfContainedTemplate>
a owl:DatatypeProperty .
display:isSelfContainedTemplate
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#menuPosition>
a owl:DatatypeProperty ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#displayLimitAnnot>
display:menuPosition
a owl:DatatypeProperty ;
vitro:displayLimitAnnot
"1"^^xsd:int .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#linkText>
a owl:DatatypeProperty .
display:linkText
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasMenuText>
a owl:DatatypeProperty .
display:hasMenuText
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#usesDataGetterClass>
a owl:DatatypeProperty .
display:usesDataGetterClass
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#query>
display:query
a owl:DatatypeProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
display:saveToVar
a owl:DatatypeProperty.
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#queryModel>
display:queryModel
a owl:DatatypeProperty.
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
display:htmlValue
a owl:DatatypeProperty.
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#cannotDeletePage>
display:cannotDeletePage
a owl:DatatypeProperty.
######### Object Properties#########
@ -134,12 +137,11 @@ rdfs:range
rdfs:domain
a owl:ObjectProperty .
owl:topObjectProperty
a owl:ObjectProperty .
##Adding object property defining class for solr data getter
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasVClassId>
a owl:ObjectProperty.
a owl:ObjectProperty .
display:hasVClassId
a owl:ObjectProperty ;
rdfs:comment "Object property defining class for solr data getter" .
###Vitro properties without which individual templates throw errors as are required
@ -148,71 +150,73 @@ owl:topObjectProperty
rdfs:range <http://vitro.mannlib.cornell.edu/ns/vitro/public#File> ;
rdfs:subPropertyOf <http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage> , owl:topObjectProperty .
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#primaryLink>
vitro:primaryLink
a owl:ObjectProperty ;
rdfs:label "Primary Link"@en-US ;
rdfs:range <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#Link> ;
rdfs:subPropertyOf <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#primaryLink> , owl:topObjectProperty ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#customEntryFormAnnot>
rdfs:range vitro:Link ;
rdfs:subPropertyOf vitro:primaryLink , owl:topObjectProperty ;
vitro:customEntryFormAnnot
"defaultLinkForm.jsp"^^xsd:string ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#forceStubDeletionAnnot>
vitro:forceStubDeletionAnnot
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#offerCreateNewOptionAnnot>
vitro:offerCreateNewOptionAnnot
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#selectFromExistingAnnot>
vitro:selectFromExistingAnnot
"false"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#stubObjectPropertyAnnot>
vitro:stubObjectPropertyAnnot
"true"^^xsd:boolean .
rdf:type
a owl:ObjectProperty ;
rdfs:label "RDF Type"@en-US ;
rdfs:range owl:Class ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#customEntryFormAnnot>
vitro:customEntryFormAnnot
"edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.RdfTypeGenerator"^^xsd:string ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#offerCreateNewOptionAnnot>
vitro:offerCreateNewOptionAnnot
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#selectFromExistingAnnot>
vitro:selectFromExistingAnnot
"true"^^xsd:boolean .
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#additionalLink>
vitro:additionalLink
a owl:ObjectProperty ;
rdfs:label "Additional Link"@en-US ;
rdfs:range <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#Link> ;
rdfs:subPropertyOf <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#additionalLink> , owl:topObjectProperty ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#customEntryFormAnnot>
rdfs:range vitro:Link ;
rdfs:subPropertyOf vitro:additionalLink , owl:topObjectProperty ;
vitro:customEntryFormAnnot
"defaultLinkForm.jsp"^^xsd:string ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#forceStubDeletionAnnot>
vitro:forceStubDeletionAnnot
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#offerCreateNewOptionAnnot>
vitro:offerCreateNewOptionAnnot
"true"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#selectFromExistingAnnot>
vitro:selectFromExistingAnnot
"false"^^xsd:boolean ;
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#stubObjectPropertyAnnot>
vitro:stubObjectPropertyAnnot
"true"^^xsd:boolean .
###Display model
###Adding menu management customform annotation
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasElement>
display:hasElement
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#excludeClass>
display:excludeClass
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#toPage>
display:toPage
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#forClassGroup>
display:forClassGroup
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
display:hasDataGetter
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#getIndividualsForClass>
display:getIndividualsForClass
a owl:ObjectProperty .
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#restrictResultsByClass>
display:restrictResultsByClass
a owl:ObjectProperty .
display:requiresAction
a owl:ObjectProperty .

View file

@ -27,55 +27,55 @@ public class SimplePermission extends Permission {
private static final Map<String, SimplePermission> allInstances = new HashMap<String, SimplePermission>();
public static final SimplePermission ACCESS_SPECIAL_DATA_MODELS = new SimplePermission(
"AccessSpecialDataModels");
NAMESPACE + "AccessSpecialDataModels");
public static final SimplePermission DO_BACK_END_EDITING = new SimplePermission(
"DoBackEndEditing");
NAMESPACE + "DoBackEndEditing");
public static final SimplePermission DO_FRONT_END_EDITING = new SimplePermission(
"DoFrontEndEditing");
NAMESPACE + "DoFrontEndEditing");
public static final SimplePermission EDIT_ONTOLOGY = new SimplePermission(
"EditOntology");
NAMESPACE + "EditOntology");
public static final SimplePermission EDIT_OWN_ACCOUNT = new SimplePermission(
"EditOwnAccount");
NAMESPACE + "EditOwnAccount");
public static final SimplePermission EDIT_SITE_INFORMATION = new SimplePermission(
"EditSiteInformation");
NAMESPACE + "EditSiteInformation");
public static final SimplePermission LOGIN_DURING_MAINTENANCE = new SimplePermission(
"LoginDuringMaintenance");
NAMESPACE + "LoginDuringMaintenance");
public static final SimplePermission MANAGE_MENUS = new SimplePermission(
"ManageMenus");
NAMESPACE + "ManageMenus");
public static final SimplePermission MANAGE_OWN_PROXIES = new SimplePermission(
"ManageOwnProxies");
NAMESPACE + "ManageOwnProxies");
public static final SimplePermission MANAGE_PORTALS = new SimplePermission(
"ManagePortals");
NAMESPACE + "ManagePortals");
public static final SimplePermission MANAGE_PROXIES = new SimplePermission(
"ManageProxies");
NAMESPACE + "ManageProxies");
public static final SimplePermission MANAGE_SEARCH_INDEX = new SimplePermission(
"ManageSearchIndex");
NAMESPACE + "ManageSearchIndex");
public static final SimplePermission MANAGE_TABS = new SimplePermission(
"ManageTabs");
NAMESPACE + "ManageTabs");
public static final SimplePermission MANAGE_USER_ACCOUNTS = new SimplePermission(
"ManageUserAccounts");
NAMESPACE + "ManageUserAccounts");
public static final SimplePermission QUERY_FULL_MODEL = new SimplePermission(
"QueryFullModel");
NAMESPACE + "QueryFullModel");
public static final SimplePermission QUERY_USER_ACCOUNTS_MODEL = new SimplePermission(
"QueryUserAccountsModel");
NAMESPACE + "QueryUserAccountsModel");
public static final SimplePermission REBUILD_VCLASS_GROUP_CACHE = new SimplePermission(
"RebuildVClassGroupCache");
NAMESPACE + "RebuildVClassGroupCache");
public static final SimplePermission REFRESH_VISUALIZATION_CACHE = new SimplePermission(
"RefreshVisualizationCache");
NAMESPACE + "RefreshVisualizationCache");
public static final SimplePermission SEE_INDVIDUAL_EDITING_PANEL = new SimplePermission(
"SeeIndividualEditingPanel");
NAMESPACE + "SeeIndividualEditingPanel");
public static final SimplePermission SEE_REVISION_INFO = new SimplePermission(
"SeeRevisionInfo");
NAMESPACE + "SeeRevisionInfo");
public static final SimplePermission SEE_SITE_ADMIN_PAGE = new SimplePermission(
"SeeSiteAdminPage");
NAMESPACE + "SeeSiteAdminPage");
public static final SimplePermission SEE_STARTUP_STATUS = new SimplePermission(
"SeeStartupStatus");
NAMESPACE + "SeeStartupStatus");
public static final SimplePermission SEE_VERBOSE_PROPERTY_INFORMATION = new SimplePermission(
"SeeVerbosePropertyInformation");
NAMESPACE + "SeeVerbosePropertyInformation");
public static final SimplePermission USE_ADVANCED_DATA_TOOLS_PAGES = new SimplePermission(
"UseAdvancedDataToolsPages");
NAMESPACE + "UseAdvancedDataToolsPages");
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
"UseSparqlQueryPage");
NAMESPACE + "UseSparqlQueryPage");
// ----------------------------------------------------------------------
// These instances are "catch all" permissions to cover poorly defined
@ -84,33 +84,35 @@ public class SimplePermission extends Permission {
// ----------------------------------------------------------------------
public static final SimplePermission USE_BASIC_AJAX_CONTROLLERS = new SimplePermission(
"UseBasicAjaxControllers");
NAMESPACE + "UseBasicAjaxControllers");
public static final SimplePermission USE_MISCELLANEOUS_ADMIN_PAGES = new SimplePermission(
"UseMiscellaneousAdminPages");
NAMESPACE + "UseMiscellaneousAdminPages");
public static final SimplePermission USE_MISCELLANEOUS_CURATOR_PAGES = new SimplePermission(
"UseMiscellaneousCuratorPages");
NAMESPACE + "UseMiscellaneousCuratorPages");
public static final SimplePermission USE_MISCELLANEOUS_EDITOR_PAGES = new SimplePermission(
"UseMiscellaneousEditorPages");
NAMESPACE + "UseMiscellaneousEditorPages");
public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission(
"UseMiscellaneousPages");
NAMESPACE + "UseMiscellaneousPages");
public static List<SimplePermission> getAllInstances() {
return new ArrayList<SimplePermission>(allInstances.values());
}
private final String localName;
//private final String localName;
private final String uri;
public final RequestedAction ACTION;
public final Actions ACTIONS;
public SimplePermission(String localName) {
super(NAMESPACE + localName);
public SimplePermission(String uri) {
super(uri);
if (localName == null) {
throw new NullPointerException("name may not be null.");
if (uri == null) {
throw new NullPointerException("uri may not be null.");
}
this.localName = localName;
this.ACTION = new SimpleRequestedAction(localName);
//this.localName = localName;
this.uri = uri;
this.ACTION = new SimpleRequestedAction(uri);
this.ACTIONS = new Actions(this.ACTION);
if (allInstances.containsKey(this.uri)) {
@ -120,14 +122,6 @@ public class SimplePermission extends Permission {
allInstances.put(uri, this);
}
public String getLocalName() {
return this.localName;
}
public String getNamespace() {
return NAMESPACE;
}
@Override
public boolean isAuthorized(RequestedAction whatToAuth) {
if (whatToAuth != null) {
@ -142,7 +136,7 @@ public class SimplePermission extends Permission {
@Override
public String toString() {
return "SimplePermission['" + localName + "']";
return "SimplePermission['" + uri+ "']";
}
}

View file

@ -0,0 +1,21 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import java.util.List;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
/**
* Policy decision that is made from some analysis of a set of decisions.
* @author bdc34
*
*/
public class CompositPolicyDecision extends BasicPolicyDecision implements PolicyDecision {
List<PolicyDecision> subDecisions;
public CompositPolicyDecision(Authorization auth, String message, List<PolicyDecision> subDecisions){
super( auth, message);
this.subDecisions = subDecisions;
}
}

View file

@ -17,8 +17,10 @@ import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
@ -26,6 +28,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPro
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.BasicAuthenticator;
/**
* A collection of static methods to help determine whether requested actions
@ -62,6 +67,48 @@ public class PolicyHelper {
return Actions.notNull(actions).isAuthorized(policy, ids);
}
/**
* Is the email/password authorized for these actions?
* This should be used when a controller or something needs allow
* actions if the user passes in their email and password.
*
* It may be better to check this as part of a servlet Filter and
* add an identifier bundle.
*/
public static boolean isAuthorizedForActions( HttpServletRequest req,
String email, String password,
Actions actions){
if( password == null || email == null ||
password.isEmpty() || email.isEmpty()){
return false;
}
try{
Authenticator basicAuth = new BasicAuthenticator(req);
UserAccount user = basicAuth.getAccountForInternalAuth( email );
log.debug("userAccount is " + user==null?"null":user.getUri() );
if( ! basicAuth.isCurrentPassword( user, password ) ){
log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri()));
return false;
}else{
log.debug(String.format("password accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri() ));
// figure out if that account can do the actions
IdentifierBundle ids =
ActiveIdentifierBundleFactories.getUserIdentifierBundle(req,user);
PolicyIface policy = ServletPolicyList.getPolicies(req);
return PolicyHelper.isAuthorizedForActions( ids, policy, actions );
}
}catch(Exception ex){
log.error("Error while attempting to authorize actions " + actions.toString(), ex);
return false;
}
}
/**
* Do the current policies authorize the current user to add this statement
* to this model?
@ -260,6 +307,7 @@ public class PolicyHelper {
+ stmt.getObject() + ">";
}
/**
* No need to instantiate this helper class - all methods are static.
*/

View file

@ -4,6 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -12,6 +14,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AllRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AnyRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
@ -38,8 +42,68 @@ public class PolicyList extends ArrayList<PolicyIface> implements PolicyIface{
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth) {
PolicyDecision pd = null;
for(PolicyIface policy : this){
if( whatToAuth instanceof AllRequestedAction ){
return doAllAction( whoToAuth, ((AllRequestedAction)whatToAuth));
}else if ( whatToAuth instanceof AnyRequestedAction ){
return doAnyAction(whoToAuth, ((AnyRequestedAction)whatToAuth));
}else{
return checkAgainstPolicys( whoToAuth , whatToAuth);
}
}
/**
* Checks that at least one of the subRequestedActions are authorized.
*/
private PolicyDecision doAnyAction(IdentifierBundle whoToAuth,
AnyRequestedAction whatToAuth) {
boolean anyAuth = false;
List<PolicyDecision> subPd = new LinkedList<PolicyDecision>();
for( RequestedAction subAct : whatToAuth.getRequestedActions()){
PolicyDecision pd = isAuthorized(whoToAuth,subAct);
subPd.add(pd);
if( pd.getAuthorized() == Authorization.AUTHORIZED){
anyAuth = true;
break;
}
}
if( anyAuth )
return new CompositPolicyDecision( Authorization.AUTHORIZED,
"Some sub-RequestedAction authorized", subPd);
else
return new CompositPolicyDecision( Authorization.UNAUTHORIZED,
"None of the sub-RequestedAction were authorized", subPd);
}
/**
* Checks that all the subRequestedActions are authorized.
*/
private PolicyDecision doAllAction(IdentifierBundle whoToAuth, AllRequestedAction whatToAuth) {
boolean allAuth = true;
List<PolicyDecision> subPd = new LinkedList<PolicyDecision>();
for( RequestedAction subAct : whatToAuth.getRequestedActions()){
PolicyDecision pd = isAuthorized( whoToAuth, subAct) ;
subPd.add( pd );
if( pd.getAuthorized() != Authorization.AUTHORIZED ){
allAuth = false;
break;
}
}
if( allAuth )
return new CompositPolicyDecision(
Authorization.AUTHORIZED,
"All sub-RequestedActions authorized.", subPd );
else
return new CompositPolicyDecision(
Authorization.UNAUTHORIZED,
"Not all sub-RequestedActions authorized.", subPd );
}
protected PolicyDecision checkAgainstPolicys( IdentifierBundle whoToAuth, RequestedAction whatToAuth){
PolicyDecision pd = null;
for(PolicyIface policy : this){
try{
pd = policy.isAuthorized(whoToAuth, whatToAuth);
if( pd != null ){
@ -47,8 +111,8 @@ public class PolicyList extends ArrayList<PolicyIface> implements PolicyIface{
break;
if( pd.getAuthorized() == Authorization.UNAUTHORIZED )
break;
// if( pd.getAuthorized() == Authorization.INCONCLUSIVE )
// continue;
if( pd.getAuthorized() == Authorization.INCONCLUSIVE )
continue;
} else{
log.debug("policy " + policy.toString() + " returned a null PolicyDecision");
}
@ -58,6 +122,6 @@ public class PolicyList extends ArrayList<PolicyIface> implements PolicyIface{
}
log.debug("decision " + pd + " for " + whatToAuth);
return pd;
}
}
}

View file

@ -2,6 +2,11 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces;
/**
* Object to represent a decision from a policy. The intent is
* that the message would be presented to users to indicate why
* they are not authorized for some action.
*/
public interface PolicyDecision {
public Authorization getAuthorized();

View file

@ -21,12 +21,16 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* An immutable list of OR and AND relationships for the required
* authorizations. A group of AND relationships is a "clause", and the list of
* clauses are in an OR relationship.
* A list of RequiredAction objects.
*
* Authorization is successful if ALL of the actions in ANY of the clauses are
* Authorization is considered successful if ALL of the actions are
* authorized, or if there are NO clauses.
*
* A previous version of this class had a capability to do OR clauses but
* this feature was unused and hindered composition of Actions
* objects. The ability to do an OR has been moved to AnyRequestedAction
* and AllRequestedAction.
*
*/
public class Actions {
private static final Log log = LogFactory.getLog(Actions.class);
@ -39,104 +43,194 @@ public class Actions {
return (actions == null) ? AUTHORIZED : actions;
}
private final List<Set<RequestedAction>> clauseList;
/**
* This is a set of RequestedActions that get ANDed together.
*
* If all of the RequestedAction objects from the
* Sets are authorized, then the Actions object should
* be considered authorized.
*/
private Set<RequestedAction> requestedActions;
public Actions(){
requestedActions= Collections.emptySet();
}
/**
* AND together all the RequestedAction from all the actions.
*/
public Actions(Actions... actions){
Set<RequestedAction> newActs = new HashSet<RequestedAction>();
for( Actions actionToAnd : actions){
if( actionToAnd != null && actionToAnd.requestedActions != null ){
newActs.addAll( actionToAnd.requestedActions );
}
}
this.requestedActions = Collections.unmodifiableSet( newActs );
}
public Actions(RequestedAction... actions) {
this(Arrays.asList(actions));
}
public Actions(Collection<RequestedAction> actions) {
this(Collections.<Set<RequestedAction>> emptyList(), actions);
this(Collections.<RequestedAction> emptySet(), actions);
}
private Actions(List<Set<RequestedAction>> oldList,
Collection<RequestedAction> newActions) {
List<Set<RequestedAction>> newList = new ArrayList<Set<RequestedAction>>();
newList.addAll(oldList);
private Actions(Set<RequestedAction> oldList,
Collection<RequestedAction> newActions) {
Set<RequestedAction> newActionSet = new HashSet<RequestedAction>(
newActions);
if (!newActionSet.isEmpty()) {
newList.add(Collections.unmodifiableSet(newActionSet));
Set<RequestedAction> newActs = new HashSet<RequestedAction>();
if( oldList != null ){
newActs.addAll(oldList);
}
this.clauseList = Collections.unmodifiableList(newList);
if ( newActions != null ) {
newActs.addAll( newActions );
}
this.requestedActions = Collections.unmodifiableSet(newActs);
}
/** require all RequestedActions on this and the ones in newActions to authorize.*/
public Actions and(RequestedAction... newActions){
return and(Arrays.asList( newActions));
}
/** require all RequestedActions on this and the ones in newActions to authorize.*/
public Actions and(Collection<RequestedAction> newActions){
if( newActions == null || newActions.size() == 0)
return this;
else
return new Actions( this.requestedActions, newActions);
}
/** require all RequestedActions on this and the ones in newActions to authorize.*/
public Actions and(Actions newActions){
return new Actions( this.requestedActions, newActions.requestedActions);
}
public Actions or(RequestedAction... newActions) {
return or(Arrays.asList(newActions));
}
/**
* OR together this.requestedActions and newActions.
*/
public Actions or(Collection<RequestedAction> newActions) {
return new Actions(this.clauseList, newActions);
RequestedAction acts;
if( newActions == null || newActions.size() == 0 ){
return this;
}
int thisActionCount = this.requestedActions.size();
int newActionCount = newActions.size();
/* This minimizes the number of extra RequestedActions
* that get created when there is only one in this
* or newActions.*/
if( thisActionCount == 1 && newActionCount == 1 ){
return new Actions(
new AnyRequestedAction(
this.requestedActions.iterator().next(),
newActions.iterator().next() ));
}
if( thisActionCount == 1 && newActionCount > 1 ){
return new Actions(
new AnyRequestedAction(
this.requestedActions.iterator().next(),
new AllRequestedAction( newActions )));
}
if( thisActionCount > 1 && newActionCount == 1){
return new Actions( new AnyRequestedAction(
new AllRequestedAction( this.requestedActions),
newActions.iterator().next()));
}
if( thisActionCount > 1 && newActionCount > 1 ){
return new Actions(
new AnyRequestedAction(
new AllRequestedAction( this.requestedActions ),
new AllRequestedAction( newActions )));
}
//should never be reached.
log.error("Could not properly create disjunction");
return null;
}
public boolean isEmpty() {
for (Set<RequestedAction> clause : clauseList) {
if (!clause.isEmpty()) {
return false;
}
}
return true;
return this.requestedActions.isEmpty();
}
/** No clauses means everything is authorized */
/**
* Are the RequestedAction objects for this Actions authorized
* with the ids and policy?
*/
public boolean isAuthorized(PolicyIface policy, IdentifierBundle ids) {
if (clauseList.isEmpty()) {
/* No clauses means everything is authorized */
if (requestedActions.isEmpty()) {
log.debug("Empty Actions is authorized");
return true;
}
return isAuthorizedForClauseList(policy, ids);
}
/** Any entire clause is good enough. */
private boolean isAuthorizedForClauseList(PolicyIface policy,
IdentifierBundle ids) {
for (Set<RequestedAction> clause : clauseList) {
if (isAuthorizedForClause(policy, ids, clause)) {
return true;
}
/* Are all the RequestedAction object authorized? */
List<PolicyDecision> decisions = new ArrayList<PolicyDecision>();
for (RequestedAction action : requestedActions) {
PolicyDecision decision = policy.isAuthorized(ids, action);
log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
+ decision);
decisions.add( decision );
}
return false;
return areAllAuthorized( decisions );
}
/** All actions in a clause must be authorized. */
private static boolean isAuthorizedForClause(PolicyIface policy,
IdentifierBundle ids, Set<RequestedAction> clause) {
for (RequestedAction action : clause) {
if (!isAuthorizedForAction(policy, ids, action)) {
log.debug("not authorized");
return false;
}
}
return true;
private boolean areAllAuthorized( List<PolicyDecision> decisions ){
for( PolicyDecision dec : decisions){
if( dec == null || dec.getAuthorized() != Authorization.AUTHORIZED ){
return false;
}
}
return true;
}
/** Is this action authorized? */
private static boolean isAuthorizedForAction(PolicyIface policy,
IdentifierBundle ids, RequestedAction action) {
PolicyDecision decision = policy.isAuthorized(ids, action);
log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
+ decision);
return (decision != null)
&& (decision.getAuthorized() == Authorization.AUTHORIZED);
}
// /** All actions in a clause must be authorized. */
// private static boolean isAuthorizedForClause(PolicyIface policy,
// IdentifierBundle ids, Set<RequestedAction> clause) {
// for (RequestedAction action : clause) {
// if (!isAuthorizedForAction(policy, ids, action)) {
// log.debug("not authorized");
// return false;
// }
// }
// return true;
// }
//
// /** Is this action authorized? */
// private static boolean isAuthorizedForAction(PolicyIface policy,
// IdentifierBundle ids, RequestedAction action) {
// PolicyDecision decision = policy.isAuthorized(ids, action);
// log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
// + decision);
// return (decision != null)
// && (decision.getAuthorized() == Authorization.AUTHORIZED);
// }
@Override
public String toString() {
StringBuffer sb = new StringBuffer("Actions[");
for (Iterator<Set<RequestedAction>> cit = clauseList.iterator(); cit.hasNext();) {
Set<RequestedAction> clause = cit.next();
sb.append("(");
for (Iterator<RequestedAction> it = clause.iterator(); it.hasNext();) {
RequestedAction action = it.next();
sb.append(action.getClass().getSimpleName());
if (it.hasNext()) {
sb.append(", ");
}
}
sb.append(")");
if (cit.hasNext()) {
sb.append(" or ");
Iterator<RequestedAction> it = this.requestedActions.iterator();
while( it.hasNext() ){
RequestedAction act = it.next();
sb.append( act.toString() );
if (it.hasNext()) {
sb.append(", ");
}
}
sb.append("]");
@ -144,10 +238,46 @@ public class Actions {
}
/**
* Nobody knows about this action class, so only the root user should be
* authorized for it.
* AND for Actions.
* ANDing with an Action with multiple disjoint clauses is not supported.
*
* To do the AND, we take each ORed clause, and add all of the RequestedActions
* so now in each of the alternative clauses, all of the singleClauseToAnd
* RequestedActions are required.
*
* @throws Exception when multiple disjoint clauses are present on both Actions.
*/
private static class UnauthorizedAction extends RequestedAction {
// no members
}
//private void andWithAction( Actions otherAct ) throws Exception{
// Set<RequestedAction> singleClauseToAnd;
// List<Set<RequestedAction>> clauses;
//
// if( otherAct.singleAndClause() ){
// clauses = this.requestedActions;
// singleClauseToAnd = otherAct.requestedActions.get(0);
// }else if( this.singleAndClause() ){
// clauses = new ArrayList<Set<RequestedAction>>( otherAct.requestedActions );
// singleClauseToAnd = this.requestedActions.get(0);
// }else{
// //both have multiple ORed clauses, give up
// throw new Exception("ANDing with an Action with multiple disjoint clauses is not supported.");
// }
//
// //
// for( Set<RequestedAction> clause : clauses){
// clause.addAll( singleClauseToAnd );
// }
// this.requestedActions = clauses;
//}
// private boolean singleAndClause(){
// return requestedActions.size() == 1;
// }
// /**
// * Nobody knows about this action class, so only the root user should be
// * authorized for it.
// */
// private static class UnauthorizedAction extends RequestedAction {
// // no members
// }
}

View file

@ -0,0 +1,26 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* This action should be authorized if all of its subActions are authorized.
* @author bdc34
*/
public class AllRequestedAction extends RequestedAction{
private final Collection<RequestedAction> subActions ;
public AllRequestedAction(RequestedAction... actions ){
this( Arrays.asList( actions ));
}
public AllRequestedAction(Collection <RequestedAction> subActions){
this.subActions = Collections.unmodifiableCollection( subActions );
}
public Collection<RequestedAction> getRequestedActions(){
return subActions;
}
}

View file

@ -0,0 +1,25 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
public class AnyRequestedAction extends RequestedAction {
private final Collection<RequestedAction> subActions ;
public AnyRequestedAction(RequestedAction... acts){
this( Arrays.asList( acts) );
}
public AnyRequestedAction(Collection<RequestedAction> subActions){
this.subActions = Collections.unmodifiableCollection( subActions );
}
public Collection<RequestedAction> getRequestedActions(){
return subActions;
}
}

View file

@ -0,0 +1,11 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* Action that should always be authorized. Mainly for testing.
* @author bdc34
*/
public class AuthorizedAction extends RequestedAction{
}

View file

@ -8,31 +8,31 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
* A RequestedAction that can be recognized by a SimplePermission.
*/
public class SimpleRequestedAction extends RequestedAction {
private final String localName;
private final String uri;
public SimpleRequestedAction(String localName) {
if (localName == null) {
throw new NullPointerException("localName may not be null.");
public SimpleRequestedAction(String uri) {
if (uri == null) {
throw new NullPointerException("uri may not be null.");
}
this.localName = localName;
this.uri = uri;
}
@Override
public String getURI() {
return "java:" + this.getClass().getName() + "#" + localName;
return uri;
}
@Override
public int hashCode() {
return (localName == null) ? 0 : localName.hashCode();
return uri.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof SimpleRequestedAction) {
SimpleRequestedAction that = (SimpleRequestedAction) o;
return equivalent(this.localName, that.localName);
return equivalent(this.uri, that.uri);
}
return false;
}
@ -43,7 +43,7 @@ public class SimpleRequestedAction extends RequestedAction {
@Override
public String toString() {
return "SimpleRequestedAction['" + localName + "']";
return "SimpleRequestedAction['" + uri + "']";
}
}

View file

@ -0,0 +1,11 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
* Action that is always unauthorized. Mainly for testing.
* @author bdc34
*/
public class UnauthorizedAction extends RequestedAction{
}

View file

@ -0,0 +1,34 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Interface to objects that provide a list of Actions that are
* required for the object to be used.
*
* This is intended to provide a way to setup DataGetter
* objects to be used with the FreemarkerHttpServlet.requiredActions()
* method.
*
* @author bdc34
*/
public interface RequiresActions {
/**
* Returns Actions that are required to be authorized for
* the object to be used.
*
* The code that is calling this method
* could use methods from PolicyHelper to check if the
* request has authorization to do these Actions. The code
* calling this method would then have the ability to
* deny the action if it is not authorized.
*
* @param vreq
* @return Should not be null. Return Actions.AUTHORIZED
* if no authorization is required to do use the object.
*/
public Actions requiredActions(VitroRequest vreq) ;
}

View file

@ -3,6 +3,7 @@
package edu.cornell.mannlib.vitro.webapp.controller;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
@ -21,6 +22,10 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.github.jsonldjava.core.JSONLD;
import com.github.jsonldjava.core.JSONLDProcessingError;
import com.github.jsonldjava.impl.JenaRDFParser;
import com.github.jsonldjava.utils.JSONUtils;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
@ -37,6 +42,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
@ -44,7 +51,7 @@ import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
/**
* Services a sparql query. This will return a simple error message and a 501 if
* there is no jena Model.
* there is no Model.
*
* @author bdc34
*
@ -52,34 +59,32 @@ import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
public class SparqlQueryServlet extends BaseEditController {
private static final Log log = LogFactory.getLog(SparqlQueryServlet.class.getName());
protected static HashMap<String,ResultSetFormat>formatSymbols = new HashMap<String,ResultSetFormat>();
static{
formatSymbols.put( ResultSetFormat.syntaxXML.getSymbol(), ResultSetFormat.syntaxXML);
formatSymbols.put( ResultSetFormat.syntaxRDF_XML.getSymbol(), ResultSetFormat.syntaxRDF_XML);
formatSymbols.put( ResultSetFormat.syntaxRDF_N3.getSymbol(), ResultSetFormat.syntaxRDF_N3);
formatSymbols.put( ResultSetFormat.syntaxText.getSymbol() , ResultSetFormat.syntaxText);
formatSymbols.put( ResultSetFormat.syntaxJSON.getSymbol() , ResultSetFormat.syntaxJSON);
formatSymbols.put( "vitro:csv", null);
}
private final static boolean CONVERT = true;
protected static HashMap<String,String> rdfFormatSymbols = new HashMap<String,String>();
static {
rdfFormatSymbols.put( "RDF/XML", "application/rdf+xml" );
rdfFormatSymbols.put( "RDF/XML-ABBREV", "application/rdf+xml" );
rdfFormatSymbols.put( "N3", "text/n3" );
rdfFormatSymbols.put( "N-TRIPLE", "text/plain" );
rdfFormatSymbols.put( "TTL", "application/x-turtle" );
}
/**
* format configurations for SELECT queries.
*/
protected static HashMap<String,RSFormatConfig> rsFormats = new HashMap<String,RSFormatConfig>();
protected static HashMap<String, String>mimeTypes = new HashMap<String,String>();
static{
mimeTypes.put( ResultSetFormat.syntaxXML.getSymbol() , "text/xml" );
mimeTypes.put( ResultSetFormat.syntaxRDF_XML.getSymbol(), "application/rdf+xml" );
mimeTypes.put( ResultSetFormat.syntaxRDF_N3.getSymbol(), "text/plain" );
mimeTypes.put( ResultSetFormat.syntaxText.getSymbol() , "text/plain");
mimeTypes.put( ResultSetFormat.syntaxJSON.getSymbol(), "application/javascript" );
mimeTypes.put( "vitro:csv", "text/csv");
}
private static RSFormatConfig[] rsfs = {
new RSFormatConfig( "RS_XML", !CONVERT, ResultFormat.XML, null, "text/xml"),
new RSFormatConfig( "RS_TEXT", !CONVERT, ResultFormat.TEXT, null, "text/plain"),
new RSFormatConfig( "vitro:csv", !CONVERT, ResultFormat.CSV, null, "text/csv"),
new RSFormatConfig( "RS_JSON", !CONVERT, ResultFormat.JSON, null, "application/javascript") };
/**
* format configurations for CONSTRUCT/DESCRIBE queries.
*/
protected static HashMap<String,ModelFormatConfig> modelFormats =
new HashMap<String,ModelFormatConfig>();
private static ModelFormatConfig[] fmts = {
new ModelFormatConfig("RDF/XML", !CONVERT, ModelSerializationFormat.RDFXML, null, "application/rdf+xml" ),
new ModelFormatConfig("RDF/XML-ABBREV", CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ),
new ModelFormatConfig("N3", !CONVERT, ModelSerializationFormat.N3, null, "text/n3" ),
new ModelFormatConfig("N-TRIPLE", !CONVERT, ModelSerializationFormat.NTRIPLE, null, "text/plain" ),
new ModelFormatConfig("TTL", CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ),
new ModelFormatConfig("JSON-LD", CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) };
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
@ -119,9 +124,9 @@ public class SparqlQueryServlet extends BaseEditController {
if( queryParam == null || "".equals(queryParam) ||
resultFormatParam == null || "".equals(resultFormatParam) ||
!formatSymbols.containsKey(resultFormatParam) ||
!rsFormats.containsKey( resultFormatParam ) ||
rdfResultFormatParam == null || "".equals(rdfResultFormatParam) ||
!rdfFormatSymbols.keySet().contains(rdfResultFormatParam) ) {
!modelFormats.containsKey( rdfResultFormatParam ) ) {
doHelp(request,response);
return;
}
@ -136,8 +141,6 @@ public class SparqlQueryServlet extends BaseEditController {
String rdfResultFormatParam,
String queryParam,
RDFService rdfService ) throws IOException {
ResultSetFormat rsf = null;
/* BJL23 2008-11-06
* modified to support CSV output.
* Unfortunately, ARQ doesn't make it easy to
@ -145,58 +148,120 @@ public class SparqlQueryServlet extends BaseEditController {
* ResultSetFormatter is hardwired with expected values.
* This slightly ugly approach will have to do for now.
*/
if ( !("vitro:csv").equals(resultFormatParam) ) {
rsf = formatSymbols.get(resultFormatParam);
}
String mimeType = mimeTypes.get(resultFormatParam);
// if ( !("vitro:csv").equals(resultFormatParam) ) {
// rsf = selectFormatSymbols.get(resultFormatParam);
// }
// String mimeType = rdfFormatToMimeType.get(resultFormatParam);
try{
Query query = SparqlQueryUtils.create(queryParam);
if( query.isSelectType() ){
ResultSet results = null;
results = ResultSetFactory.fromJSON(rdfService.sparqlSelectQuery(
queryParam, RDFService.ResultFormat.JSON));
response.setContentType(mimeType);
if (rsf != null) {
OutputStream out = response.getOutputStream();
ResultSetFormatter.output(out, results, rsf);
} else {
Writer out = response.getWriter();
toCsv(out, results);
}
doSelectQuery( queryParam, rdfService, resultFormatParam, response);
} else if(query.isAskType()){
// Irrespective of the ResultFormatParam,
// this always prints a boolean to the default OutputStream.
String result = (rdfService.sparqlAskQuery(queryParam) == true)
? "true"
: "false";
PrintWriter p = response.getWriter();
p.write(result);
return;
} else {
Model resultModel = null;
if( query.isConstructType() ){
resultModel = RDFServiceUtils.parseModel(
rdfService.sparqlConstructQuery(
queryParam,
RDFService.ModelSerializationFormat.N3),
RDFService.ModelSerializationFormat.N3);
}else if ( query.isDescribeType() ){
resultModel = RDFServiceUtils.parseModel(
rdfService.sparqlDescribeQuery(
queryParam,
RDFService.ModelSerializationFormat.N3),
RDFService.ModelSerializationFormat.N3);
}else if(query.isAskType()){
// Irrespective of the ResultFormatParam,
// this always prints a boolean to the default OutputStream.
String result = (rdfService.sparqlAskQuery(queryParam) == true)
? "true"
: "false";
PrintWriter p = response.getWriter();
p.write(result);
return;
}
response.setContentType(rdfFormatSymbols.get(rdfResultFormatParam));
OutputStream out = response.getOutputStream();
resultModel.write(out, rdfResultFormatParam);
doModelResultQuery( query, rdfService, rdfResultFormatParam, response);
}
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
}
/**
* Execute the query and send the result to out. Attempt to
* send the RDFService the same format as the rdfResultFormatParam
* so that the results from the RDFService can be directly piped to the client.
* @param rdfService
* @throws IOException
* @throws RDFServiceException
*/
private void doSelectQuery( String queryParam,
RDFService rdfService, String resultFormatParam,
HttpServletResponse response) throws IOException, RDFServiceException{
RSFormatConfig config = rsFormats.get( resultFormatParam );
if( ! config.converstionFromWireFormat ){
response.setContentType( config.responseMimeType );
InputStream results = rdfService.sparqlSelectQuery(queryParam, config.wireFormat );
pipe( results, response.getOutputStream() );
}else{
//always use JSON when conversion is needed.
InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON );
response.setContentType( config.responseMimeType );
ResultSet rs = ResultSetFactory.fromJSON( results );
OutputStream out = response.getOutputStream();
ResultSetFormatter.output(out, rs, config.jenaResponseFormat);
// } else {
// Writer out = response.getWriter();
// toCsv(out, results);
//}
}
}
/**
* Execute the query and send the result to out. Attempt to
* send the RDFService the same format as the rdfResultFormatParam
* so that the results from the RDFService can be directly piped to the client.
* @param rdfService
* @throws IOException
* @throws RDFServiceException
* @throws
*/
private void doModelResultQuery( Query query,
RDFService rdfService, String rdfResultFormatParam,
HttpServletResponse response) throws IOException, RDFServiceException{
//config drives what formats and conversions to use
ModelFormatConfig config = modelFormats.get( rdfResultFormatParam );
InputStream rawResult = null;
if( query.isConstructType() ){
rawResult= rdfService.sparqlConstructQuery( query.toString(), config.wireFormat );
}else if ( query.isDescribeType() ){
rawResult = rdfService.sparqlDescribeQuery( query.toString(), config.wireFormat );
}
response.setContentType( config.responseMimeType );
if( config.converstionFromWireFormat ){
Model resultModel = RDFServiceUtils.parseModel( rawResult, config.wireFormat );
if( "JSON-LD".equals( config.jenaResponseFormat )){
//since jena 2.6.4 doesn't support JSON-LD we do it
try {
JenaRDFParser parser = new JenaRDFParser();
Object json = JSONLD.fromRDF(resultModel, parser);
JSONUtils.write(response.getWriter(), json);
} catch (JSONLDProcessingError e) {
throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e);
}
}else{
OutputStream out = response.getOutputStream();
resultModel.write(out, config.jenaResponseFormat );
}
}else{
OutputStream out = response.getOutputStream();
pipe( rawResult, out );
}
}
private void pipe( InputStream in, OutputStream out) throws IOException{
int size;
byte[] buffer = new byte[4096];
while( (size = in.read(buffer)) > -1 ) {
out.write(buffer,0,size);
}
}
private void doNoModelInContext(HttpServletResponse res){
try {
res.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
@ -290,8 +355,6 @@ public class SparqlQueryServlet extends BaseEditController {
req.setAttribute("prefixList", prefixList);
// nac26: 2009-09-25 - this was causing problems in safari on localhost installations because the href did not include the context. The edit.css is not being used here anyway (or anywhere else for that matter)
// req.setAttribute("css", "<link rel=\"stylesheet\" type=\"text/css\" href=\""+portal.getThemeDir()+"css/edit.css\"/>");
req.setAttribute("title","SPARQL Query");
req.setAttribute("bodyJsp", "/admin/sparqlquery/sparqlForm.jsp");
@ -299,4 +362,55 @@ public class SparqlQueryServlet extends BaseEditController {
rd.forward(req,res);
}
public static class ModelFormatConfig{
public String valueFromForm;
public boolean converstionFromWireFormat;
public RDFService.ModelSerializationFormat wireFormat;
public String jenaResponseFormat;
public String responseMimeType;
public ModelFormatConfig( String valueFromForm,
boolean converstionFromWireFormat,
RDFService.ModelSerializationFormat wireFormat,
String jenaResponseFormat,
String responseMimeType){
this.valueFromForm = valueFromForm;
this.converstionFromWireFormat = converstionFromWireFormat;
this.wireFormat = wireFormat;
this.jenaResponseFormat = jenaResponseFormat;
this.responseMimeType = responseMimeType;
}
}
public static class RSFormatConfig{
public String valueFromForm;
public boolean converstionFromWireFormat;
public ResultFormat wireFormat;
public ResultSetFormat jenaResponseFormat;
public String responseMimeType;
public RSFormatConfig( String valueFromForm,
boolean converstionFromWireFormat,
ResultFormat wireFormat,
ResultSetFormat jenaResponseFormat,
String responseMimeType ){
this.valueFromForm = valueFromForm;
this.converstionFromWireFormat = converstionFromWireFormat;
this.wireFormat = wireFormat;
this.jenaResponseFormat = jenaResponseFormat;
this.responseMimeType = responseMimeType;
}
}
static{
/* move the lists of configs into maps for easy lookup */
for( RSFormatConfig rsfc : rsfs ){
rsFormats.put( rsfc.valueFromForm, rsfc );
}
for( ModelFormatConfig mfc : fmts ){
modelFormats.put( mfc.valueFromForm, mfc);
}
}
}

View file

@ -45,6 +45,7 @@ public class VitroHttpServlet extends HttpServlet {
public final static String HTML_MIMETYPE = "text/html";
public final static String RDFXML_MIMETYPE = "application/rdf+xml";
public final static String JSON_MIMETYPE = "application/json";
public final static String N3_MIMETYPE = "text/n3"; // unofficial and unregistered
public final static String TTL_MIMETYPE = "text/turtle"; // unofficial and unregistered

View file

@ -179,6 +179,18 @@ public class VitroRequest extends HttpServletRequestWrapper {
return getWebappDaoFactory().getApplicationDao().getApplicationBean();
}
/**
* Gets the the ip of the client.
* This will be X-forwarded-for header or, if that header is not
* set, getRemoteAddr(). This still may not be the client's address
* as they may be using a proxy.
*
*/
public String getClientAddr(){
String xff = getHeader("x-forwarded-for");
return ( xff == null || xff.trim().isEmpty() ) ? getRemoteAddr() : xff;
}
@SuppressWarnings("unchecked")
@Override
public Map<String, String[]> getParameterMap() {

View file

@ -2,7 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import static javax.mail.Message.RecipientType.TO;
import static javax.mail.Message.RecipientType.*;
import java.io.IOException;
import java.io.PrintWriter;
@ -20,6 +20,11 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.github.jsonldjava.core.JSONLD;
import com.github.jsonldjava.core.JSONLDProcessingError;
import com.github.jsonldjava.impl.JenaRDFParser;
import com.github.jsonldjava.utils.JSONUtils;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
@ -38,6 +43,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
@ -48,7 +54,7 @@ import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap;
public class FreemarkerHttpServlet extends VitroHttpServlet {
public class FreemarkerHttpServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(FreemarkerHttpServlet.class);
@ -203,6 +209,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
* NB This method can't be static, because then the superclass method gets called rather than
* the subclass method. For the same reason, it can't refer to a static or instance field
* REQUIRED_ACTIONS which is overridden in the subclass.
*
*/
protected Actions requiredActions(VitroRequest vreq) {
return Actions.AUTHORIZED;
@ -307,16 +314,28 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
String mediaType = values.getContentType().getMediaType();
response.setContentType(mediaType);
String format = "";
if ( RDFXML_MIMETYPE.equals(mediaType)) {
format = "RDF/XML";
} else if( N3_MIMETYPE.equals(mediaType)) {
format = "N3";
} else if ( TTL_MIMETYPE.equals(mediaType)) {
format ="TTL";
if ( JSON_MIMETYPE.equals(mediaType)){
//json-ld is not supported by jena v2.6.4
try {
JenaRDFParser parser = new JenaRDFParser();
Object json = JSONLD.fromRDF( values.getModel() , parser);
JSONUtils.write(response.getWriter(), json);
} catch (JSONLDProcessingError e) {
throw new IOException("Could not convert from Jena model to JSON-LD", e);
}
}else{
String format = "";
if ( RDFXML_MIMETYPE.equals(mediaType)) {
format = "RDF/XML";
} else if( N3_MIMETYPE.equals(mediaType)) {
format = "N3";
} else if ( TTL_MIMETYPE.equals(mediaType)) {
format ="TTL";
}
values.getModel().write( response.getOutputStream(), format );
}
values.getModel().write( response.getOutputStream(), format );
}
protected void doException(VitroRequest vreq, HttpServletResponse response,

View file

@ -3,6 +3,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -17,6 +18,10 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequiresActions;
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;
@ -41,6 +46,79 @@ public class PageController extends FreemarkerHttpServlet{
protected static final String DATA_GETTER_MAP = "pageTypeToDataGetterMap";
/**
* Get the required actions for all the data getters then
* AND them together.
*/
@Override
protected Actions requiredActions(VitroRequest vreq) {
try {
Actions pageActs = getActionsForPage( vreq );
Actions dgActs = getActionsForDataGetters( vreq );
if( pageActs == null && dgActs == null){
return Actions.AUTHORIZED;
}else if( pageActs == null && dgActs != null ){
return dgActs;
}else{
return pageActs;
}
} catch (Exception e) {
// TODO Auto-generated catch block
log.debug(e);
return Actions.UNAUTHORIZED;
}
}
/**
* Get all the required actions directly required for the page.
*/
private Actions getActionsForPage( VitroRequest vreq ) throws Exception{
List<String> simplePremUris = vreq.getWebappDaoFactory().getPageDao()
.getRequiredActions( getPageUri(vreq) );
List<RequestedAction> actions = new ArrayList<RequestedAction>();
for( String uri : simplePremUris ){
actions.add( new SimpleRequestedAction(uri) );
}
return new Actions( actions );
}
/**
* Get Actions object for the data getters for the page.
*/
private Actions getActionsForDataGetters(VitroRequest vreq ){
try {
Actions dgActs = null;
List<DataGetter> dgList =
DataGetterUtils.getDataGettersForPage(
vreq, vreq.getDisplayModel(), getPageUri(vreq));
for( DataGetter dg : dgList){
if( dg instanceof RequiresActions ){
RequiresActions ra = (RequiresActions) dg;
Actions newActions = ra.requiredActions(vreq);
if( newActions != null ){
if( dgActs != null ){
dgActs = dgActs.and( newActions );
}else{
dgActs = newActions;
}
}
}
}
return dgActs;
} catch (Exception e) {
// TODO Auto-generated catch block
log.debug(e);
return Actions.UNAUTHORIZED;
}
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) throws Exception {
@ -65,8 +143,7 @@ public class PageController extends FreemarkerHttpServlet{
return doNotFound(vreq);
}
//executePageDataGetters( pageUri, vreq, getServletContext(), mapForTemplate );
//these should all be data getters now
//these should all be DataGetters now, not PageDataGetters
executeDataGetters( pageUri, vreq, mapForTemplate);
mapForTemplate.putAll( getPageControllerValues( pageUri, vreq, getServletContext(), mapForTemplate));

View file

@ -39,6 +39,8 @@ public class IndividualController extends FreemarkerHttpServlet {
map.put(HTML_MIMETYPE, 0.5f);
map.put(XHTML_MIMETYPE, 0.5f);
map.put("application/xml", 0.5f);
map.put(JSON_MIMETYPE, 1.0f);
map.put(RDFXML_MIMETYPE, 1.0f);
map.put(RDFXML_MIMETYPE, 1.0f);
map.put(N3_MIMETYPE, 1.0f);
map.put(TTL_MIMETYPE, 1.0f);

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.individual;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.N3_MIMETYPE;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.RDFXML_MIMETYPE;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.TTL_MIMETYPE;
import static edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet.JSON_MIMETYPE;
import java.util.Map;
import java.util.regex.Matcher;
@ -117,7 +118,9 @@ public class IndividualRequestAnalyzer {
return "/individual/" + m.group(1) + "/" + m.group(1) + ".n3";
} else if (TTL_MIMETYPE.equals(mediaType)) {
return "/individual/" + m.group(1) + "/" + m.group(1) + ".ttl";
}
} else if (JSON_MIMETYPE.equals(mediaType)){
return "/individual/" + m.group(1) + "/" + m.group(1) + ".jsonld";
}
}
// or redirect to the canonical URL for HTML representation.
return "/display/" + m.group(1);
@ -244,6 +247,9 @@ public class IndividualRequestAnalyzer {
if (formatParam.contains("ttl")) {
return ContentType.TURTLE;
}
if (formatParam.contains("jsonld") || formatParam.contains("json")){
return ContentType.JSON;
}
/*
* Check for parts of URL that indicate request for RDF. Examples:

View file

@ -48,6 +48,7 @@ public class DisplayVocabulary {
public static final String ITEM_TO_PAGE = NS + "toPage";
public static final String HAS_ELEMENT = NS + "hasElement";
public static final String USES_DATAGETTER_CLASS = NS + "usesDataGetterClass";
public static final String REQUIRED_ACTIONS = NS + "requiredAction";
/**Data Getter object properties **/
public static final String HAS_DATA_GETTER = NS + "hasDataGetter";

View file

@ -29,4 +29,10 @@ public interface PageDao {
List<String> getDataGetterClass(String pageUri);
/**
* Gets the required actions directly associated with a page.
* Does not get required actions for any data getters that are
* related to the page.
*/
List<String> getRequiredActions(String pageUri);
}

View file

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -78,6 +79,13 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
" ?dg rdf:type ?dataGetterType . \n" +
"} \n" ;
//Get the required actions directly associated with a page
static final protected String requiredActionsQuery =
prefixes + "\n" +
"SELECT ?requiredAction WHERE{\n" +
" ?pageUri <" + DisplayVocabulary.REQUIRED_ACTIONS + "> ?requiredAction .\n"+
"}";
//Get data getter URIs
static final protected String dataGetterURIsQueryString =
prefixes + "\n" +
@ -520,9 +528,53 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
}
/**
* Gets the requiredActions directly associated with page.
*/
public List<String> getRequiredActions(String pageUri){
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("pageUri", ResourceFactory.createResource(pageUri));
List<String> actions = new ArrayList<String>();
Model dModel = getOntModelSelector().getDisplayModel();
try{
QueryExecution qe =
QueryExecutionFactory.create( requiredActionsQuery, dModel, initialBindings);
actions = executeQueryToList( qe );
qe.close();
}finally{
dModel.enterCriticalSection(false);
}
return actions;
}
/* *************************** Utility methods ********************************* */
/**
* Assumes single bound variable in solution.
*/
protected List<String> executeQueryToList(QueryExecution qex){
List<String> rv = new LinkedList<String>();
ResultSet results = qex.execSelect();
while (results.hasNext()) {
rv.add(querySolutionToString( results.nextSolution() ));
}
return rv;
}
/**
* Assumes single bound variable in solution.
*/
protected String querySolutionToString( QuerySolution soln ){
Iterator<String> varNames = soln.varNames();
if(varNames.hasNext()){
String name = varNames.next();
return nodeToString( soln.get(name) );
}else{
return "";
}
}
/**
* Converts a sparql query that returns a multiple rows to a list of maps.
* The maps will have column names as keys to the values.
@ -549,6 +601,8 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
return map;
}
static protected Object nodeToObject( RDFNode node ){
if( node == null ){
return "";
@ -582,11 +636,6 @@ public class PageDaoJena extends JenaBaseDao implements PageDao {
return "";
}
}
protected Map<String,Object> resultsToMap(){
return null;
}
}

View file

@ -547,7 +547,8 @@ public class SimpleReasoner extends StatementListener {
*
* If it is removed that x is sameAs y, then remove y sameAs x from
* the inference graph and then recompute the inferences for x and
* y based on their respective assertions. that x owl:sameAs y, then all asserted and inferred
* y based on their respective assertions.
* that x owl:sameAs y, then all asserted and inferred
*/
protected void removedABoxSameAsAssertion(Statement stmt, Model inferenceModel) {
Resource subject = null;

View file

@ -43,7 +43,7 @@ public class SearchServiceController extends FreemarkerHttpServlet {
* userAccount associated with the email.
*/
@Override
protected Actions requiredActions(VitroRequest vreq) {
public Actions requiredActions(VitroRequest vreq) {
try{
// Works by side effect: parse the multi-part request and stash FileItems in request
FileUploadServletRequest.parseRequest(vreq, 0);
@ -52,42 +52,21 @@ public class SearchServiceController extends FreemarkerHttpServlet {
String pw = vreq.getParameter("password");
String email = vreq.getParameter("email");
log.debug(String.format("email: '%s' password: '%s' ",email,pw));
if( pw == null || email == null || pw.isEmpty() || email.isEmpty()){
return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
}
Authenticator basicAuth = new BasicAuthenticator(vreq);
UserAccount user = basicAuth.getAccountForInternalAuth( email );
log.debug("userAccount is " + user==null?"null":user.getUri() );
if( ! basicAuth.isCurrentPassword( user, pw ) ){
log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri()));
return Actions.UNAUTHORIZED;
}else{
log.debug(String.format("password accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri() ));
}
//then figure out if that account can manage the search index.
IdentifierBundle ids =
ActiveIdentifierBundleFactories.getUserIdentifierBundle(vreq,user);
PolicyIface policy = ServletPolicyList.getPolicies(vreq);
boolean canManageSearchIndex =
PolicyHelper.isAuthorizedForActions( ids, policy,
SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS );
if( canManageSearchIndex ){
if( PolicyHelper.isAuthorizedForActions(vreq, email, pw,
SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS ) ){
return Actions.AUTHORIZED;
}else{
log.debug(String.format("userAccount is unauthorized to" +
" manage the search index.",user.getUri()));
log.debug(email + " is unauthorized to manage the search index. " +
"client IP "+vreq.getClientAddr());
return Actions.UNAUTHORIZED;
}
}catch(Exception ex){
log.error("Error while attempting to log in " +
log.error("Error while client IP "+ vreq.getClientAddr() + " attempting to log in " +
"to SearchServiceController: " + ex.getMessage());
return Actions.UNAUTHORIZED;
}

View file

@ -9,8 +9,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentSkipListSet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@ -62,6 +60,9 @@ public class IndexBuilder extends VitroBackgroundThread {
/** Indicates that a stop of the indexing objects has been requested. */
private volatile boolean stopRequested = false;
/** Indicates that new updates should not be started. */
private boolean deferNewUpdates = false;
/** Length of time to wait before looking for work (if not wakened sooner). */
public static final long MAX_IDLE_INTERVAL = 1000 * 60 /* msec */ ;
@ -163,7 +164,7 @@ public class IndexBuilder extends VitroBackgroundThread {
* This will re-index Individuals were added with addToChanged().
*/
public synchronized void doUpdateIndex() {
log.debug("callto doUpdateIndex()");
log.debug("call to doUpdateIndex()");
//wake up thread and it will attempt to index anything in changedUris
this.notifyAll();
}
@ -185,11 +186,32 @@ public class IndexBuilder extends VitroBackgroundThread {
this.interrupt();
}
/**
* Calling this will cause the IndexBuider to no start a new index update
* until unpuase is called. This is intended to allow a large change
* without slowing it down with incremental search index updates.
*/
public synchronized void pause(){
this.deferNewUpdates = true;
}
public synchronized void unpause(){
if( deferNewUpdates == true ){
this.deferNewUpdates = false;
this.notifyAll();
this.interrupt();
}
}
@Override
public void run() {
while(! stopRequested ){
try{
if( reindexRequested ){
if ( deferNewUpdates ){
log.debug("there is no indexing working to do, waiting for work");
synchronized (this) { this.wait(MAX_IDLE_INTERVAL); }
}
else if ( reindexRequested ){
setWorkLevel(WorkLevel.WORKING, FLAG_REBUILDING);
log.debug("full re-index requested");
@ -198,7 +220,8 @@ public class IndexBuilder extends VitroBackgroundThread {
notifyListeners( IndexingEventListener.EventTypes.FINISH_FULL_REBUILD );
setWorkLevel(WorkLevel.IDLE);
}else{
}
else{
boolean workToDo = false;
synchronized (changedStmts ){
workToDo = !changedStmts.isEmpty();

View file

@ -56,6 +56,11 @@ public class DataGetterUtils {
final static Log log = LogFactory.getLog(DataGetterUtils.class);
/**
* Attribute name in request for DataGetters
*/
public final static String DATA_GETTERS_FOR_PAGE = "data_getters_for_page";
/**
* Get a list of DataGetter objects that are associated with a page.
* This should not return PageDataGetters and should not throw an
@ -63,10 +68,16 @@ public class DataGetterUtils {
*/
public static List<DataGetter> getDataGettersForPage(VitroRequest vreq, Model displayModel, String pageURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException {
List<String> dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForPage: " + dgList);
return dgList;
if( vreq.getAttribute(DATA_GETTERS_FOR_PAGE) != null){
return (List<DataGetter>) vreq.getAttribute(DATA_GETTERS_FOR_PAGE);
}else{
List<String> dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForPage: " + dgList);
vreq.setAttribute( DATA_GETTERS_FOR_PAGE , dgList );
return dgList;
}
}
/**

View file

@ -0,0 +1,96 @@
/* $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.HashMap;
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.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.update.GraphStore;
import com.hp.hpl.jena.update.GraphStoreFactory;
import com.hp.hpl.jena.update.UpdateAction;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequiresActions;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
/**
* Handle a SPARQL Update request. This uses Jena ARQ and the RDFServiceDataset to
* evaluate a SPARQL Update with the RDFService.
*
* The reason to make this a DataGettere was to allow configuration in RDF of this
* service.
*/
public class SparqlUpdate implements DataGetter, RequiresActions{
private static final Log log = LogFactory.getLog(SparqlUpdate.class);
VitroRequest vreq;
ServletContext context;
public SparqlUpdate(
VitroRequest vreq, Model displayModel, String dataGetterURI ) {
if( vreq == null )
throw new IllegalArgumentException("VitroRequest may not be null.");
this.vreq = vreq;
this.context = vreq.getSession().getServletContext();
}
/**
* Gets the update from the request and then executes it on
* the RDFService.
*/
@Override
public Map<String,Object> getData( Map<String, Object> valueMap ) {
HashMap<String, Object> data = new HashMap<String,Object>();
String update = vreq.getParameter("update");
if( update != null && !update.trim().isEmpty()){
try{
IndexBuilder.getBuilder(context).pause();
Dataset ds = new RDFServiceDataset( vreq.getUnfilteredRDFService() );
GraphStore graphStore = GraphStoreFactory.create(ds);
log.warn("The SPARQL update is '"+vreq.getParameter("update")+"'");
UpdateAction.parseExecute( vreq.getParameter("update") , graphStore );
}finally{
IndexBuilder.getBuilder(context).unpause();
}
}
data.put("bodyTemplate", "page-sparqlUpdateTest.ftl");
return data;
}
/**
* Check if this request is authorized by the email/password.
* If not do normal authorization.
*/
@Override
public Actions requiredActions(VitroRequest vreq) {
String email = vreq.getParameter("email");
String password = vreq.getParameter("password");
boolean isAuth = PolicyHelper.isAuthorizedForActions(vreq,
email, password, SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS);
if( isAuth )
return Actions.AUTHORIZED;
else
return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
}
}

View file

@ -0,0 +1,154 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AllRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AnyRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.UnauthorizedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
public class PolicyListTest {
@Test
public void basicPolicyListTest() {
List<PolicyIface> polis = new ArrayList<PolicyIface>();
polis.add( new SimplePolicy() );
PolicyIface policy = new PolicyList( polis );
PolicyDecision decision = policy.isAuthorized(null, new UnauthorizedAction());
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
decision = policy.isAuthorized(null, new AuthorizedAction());
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
}
/**
* Tests the handling of the AnyRequestedAction by the PolicyList.
*/
@Test
public void anyActionTest(){
List<PolicyIface> polis = new ArrayList<PolicyIface>();
polis.add( new SimplePolicy() );
PolicyIface policy = new PolicyList( polis );
AnyRequestedAction act = new AnyRequestedAction( new UnauthorizedAction() );
PolicyDecision decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new UnauthorizedAction() , new UnauthorizedAction());
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new UnauthorizedAction(),new UnauthorizedAction(),new UnauthorizedAction());
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new AuthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new AuthorizedAction(),new UnauthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new UnauthorizedAction(),new AuthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new UnauthorizedAction(),new UnauthorizedAction(),new AuthorizedAction());
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new UnauthorizedAction(),new AuthorizedAction(),new AuthorizedAction());
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AnyRequestedAction( new AuthorizedAction(),new AuthorizedAction(),new AuthorizedAction());
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
}
/**
* Tests the handling of the AllRequestedAction by the PolicyList.
*/
@Test
public void andActionTest(){
List<PolicyIface> polis = new ArrayList<PolicyIface>();
polis.add( new SimplePolicy() );
PolicyIface policy = new PolicyList( polis );
AllRequestedAction act = new AllRequestedAction( new UnauthorizedAction(), new UnauthorizedAction(), new UnauthorizedAction());
PolicyDecision decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new UnauthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new UnauthorizedAction() , new AuthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new AuthorizedAction() , new UnauthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new AuthorizedAction() , new AuthorizedAction() ,new UnauthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new AuthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
act = new AllRequestedAction( new AuthorizedAction() , new AuthorizedAction(), new AuthorizedAction() );
decision = policy.isAuthorized(null, act);
Assert.assertNotNull( decision );
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
}
/**
* policy that only responds to Unauthorized and Authorized actions.
*/
public class SimplePolicy implements PolicyIface {
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if( whatToAuth instanceof UnauthorizedAction )
return new BasicPolicyDecision( Authorization.UNAUTHORIZED, "SimplePolicy unauthorized");
if( whatToAuth instanceof AuthorizedAction )
return new BasicPolicyDecision( Authorization.AUTHORIZED, "SimplePolicy authorized");
else
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, "SimplePolicy INCONCLUSIVE");
}
}
}

View file

@ -0,0 +1,74 @@
package edu.cornell.mannlib.vitro.webapp.controller;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.github.jsonldjava.core.JSONLD;
import com.github.jsonldjava.core.JSONLDProcessingError;
import com.github.jsonldjava.impl.JenaRDFParser;
import com.github.jsonldjava.utils.JSONUtils;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
public class SparqlQueryServletTest {
@Test
public void testJSONLD() throws JSONLDProcessingError {
//just check if we can use JSONLD-JAVA
final String turtle = "@prefix const: <http://foo.com/> .\n"
+ "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n"
+ "<http://localhost:8080/foo1> const:code \"123\" .\n"
+ "<http://localhost:8080/foo2> const:code \"ABC\"^^xsd:string .\n";
final List<Map<String, Object>> expected = new ArrayList<Map<String, Object>>() {
{
add(new LinkedHashMap<String, Object>() {
{
put("@id", "http://localhost:8080/foo1");
put("http://foo.com/code", new ArrayList<Object>() {
{
add(new LinkedHashMap<String, Object>() {
{
put("@value", "123");
}
});
}
});
}
});
add(new LinkedHashMap<String, Object>() {
{
put("@id", "http://localhost:8080/foo2");
put("http://foo.com/code", new ArrayList<Object>() {
{
add(new LinkedHashMap<String, Object>() {
{
put("@value", "ABC");
}
});
}
});
}
});
}
};
final Model modelResult = ModelFactory.createDefaultModel().read(
new ByteArrayInputStream(turtle.getBytes()), "", "TURTLE");
final JenaRDFParser parser = new JenaRDFParser();
final Object json = JSONLD.fromRDF(modelResult, parser);
assertTrue(JSONUtils.equals(json, expected));
}
}

View file

@ -0,0 +1,159 @@
# $This file is distributed under the terms of the license in /doc/license.txt$
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix action: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
# These are the reqired action objects from the SimplePermission.java.
action:AccessSpecialDataModels
a display:RequiredAction ;
rdfs:label "ACCESS_SPECIAL_DATA_MODELS" .
action:DoBackEndEditing
a display:RequiredAction ;
rdfs:label "DO_BACK_END_EDITING" .
action:DoFrontEndEditing
a display:RequiredAction ;
rdfs:label "DO_FRONT_END_EDITING" .
action:EditOntology
a display:RequiredAction ;
rdfs:label "EDIT_ONTOLOGY" .
action:EditOwnAccount
a display:RequiredAction ;
rdfs:label "EDIT_OWN_ACCOUNT" .
action:EditSiteInformation
a display:RequiredAction ;
rdfs:label "EDIT_SITE_INFORMATION" .
action:LoginDuringMaintenance
a display:RequiredAction ;
rdfs:label "LOGIN_DURING_MAINTENANCE" .
action:ManageMenus
a display:RequiredAction ;
rdfs:label "MANAGE_MENUS" .
action:ManageOwnProxies
a display:RequiredAction ;
rdfs:label "MANAGE_OWN_PROXIES" .
action:ManagePortals
a display:RequiredAction ;
rdfs:label "MANAGE_PORTALS" .
action:ManageProxies
a display:RequiredAction ;
rdfs:label "MANAGE_PROXIES" .
action:ManageSearchIndex
a display:RequiredAction ;
rdfs:label "MANAGE_SEARCH_INDEX" .
action:ManageTabs
a display:RequiredAction ;
rdfs:label "MANAGE_TABS" .
action:ManageUserAccounts
a display:RequiredAction ;
rdfs:label "MANAGE_USER_ACCOUNTS" .
action:QueryFullModel
a display:RequiredAction ;
rdfs:label "QUERY_FULL_MODEL" .
action:QueryUserAccountsModel
a display:RequiredAction ;
rdfs:label "QUERY_USER_ACCOUNTS_MODEL" .
action:RebuildVClassGroupCache
a display:RequiredAction ;
rdfs:label "REBUILD_VCLASS_GROUP_CACHE" .
action:RefreshVisualizationCache
a display:RequiredAction ;
rdfs:label "REFRESH_VISUALIZATION_CACHE" .
action:SeeIndividualEditingPanel
a display:RequiredAction ;
rdfs:label "SEE_INDVIDUAL_EDITING_PANEL" .
action:SeeRevisionInfo
a display:RequiredAction ;
rdfs:label "SEE_REVISION_INFO" .
action:SeeSiteAdminPage
a display:RequiredAction ;
rdfs:label "SEE_SITE_ADMIN_PAGE" .
action:SeeStartupStatus
a display:RequiredAction ;
rdfs:label "SEE_STARTUP_STATUS" .
action:SeeVerbosePropertyInformation
a display:RequiredAction ;
rdfs:label "SEE_VERBOSE_PROPERTY_INFORMATION" .
action:UseAdvancedDataToolsPages
a display:RequiredAction ;
rdfs:label "USE_ADVANCED_DATA_TOOLS_PAGES" .
action:UseSparqlQueryPage
a display:RequiredAction ;
rdfs:label "USE_SPARQL_QUERY_PAGE" .
action:UseBasicAjaxControllers
a display:RequiredAction ;
rdfs:label "USE_BASIC_AJAX_CONTROLLERS" .
action:UseMiscellaneousAdminPages
a display:RequiredAction ;
rdfs:label "USE_MISCELLANEOUS_ADMIN_PAGES" .
action:UseMiscellaneousCuratorPages
a display:RequiredAction ;
rdfs:label "USE_MISCELLANEOUS_CURATOR_PAGES" .
action:UseMiscellaneousEditorPages
a display:RequiredAction ;
rdfs:label "USE_MISCELLANEOUS_EDITOR_PAGES" .
action:UseMiscellaneousPages
a display:RequiredAction ;
rdfs:label "USE_MISCELLANEOUS_PAGES" .

View file

@ -0,0 +1,23 @@
# $This file is distributed under the terms of the license in /doc/license.txt$
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
### page for SPARQL UPDATE ###
display:SparqlUpdateMenuItem
a display:NavigationElement ;
display:linkText "SPARQL Update";
display:toPage display:SparqlUpdatePage .
display:sparqlUpdateDataGetter
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlUpdate> .
display:SparqlUpdatePage
a display:Page ;
display:title "SPARQL Update" ;
display:urlMapping "/sparql" ;
display:hasDataGetter display:sparqlUpdateDataGetter ;
display:requiredAction <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#UseAdvancedDataToolsPages> .

View file

@ -52,6 +52,7 @@ LIMIT 20
<div>
<h3>Format for SELECT query results:</h3>
<input id='RS_XML_BUTTON' type='radio' name='resultFormat' value='RS_XML'> <label for='RS_XML_BUTTON'>RS_XML</label>
<input id='RS_TEXT_BUTTON' type='radio' name='resultFormat' value='RS_TEXT' checked='checked'> <label for='RS_TEXT_BUTTON'>RS_TEXT</label>
<input id='RS_CSV_BUTTON' type='radio' name='resultFormat' value='vitro:csv'> <label for='RS_CSV_BUTTON'>CSV</label>
@ -66,23 +67,11 @@ LIMIT 20
<input id='RR_N3_BUTTON' type='radio' name='rdfResultFormat' value='N3'> <label for='RR_N3_BUTTON'>N3</label>
<input id='RR_NTRIPLE_BUTTON' type='radio' name='rdfResultFormat' value='N-TRIPLE'> <label for='RR_NTRIPLE_BUTTON'>N-Triples</label>
<input id='RR_TURTLE_BUTTON' type='radio' name='rdfResultFormat' value='TTL'> <label for='RR_TURTLE_BUTTON'>Turtle</label>
<input id='RR_JSON_LD_BUTTON' type='radio' name='rdfResultFormat' value='JSON-LD'> <label for='RR_JSON_LD_BUTTON'>JSON-LD</label>
</div>
<input class="submit" type="submit" value="Run Query" />
</form>
<%--
<h4>Notes</h4>
<p>CONSTRUCT and DESCRIBE queries always return RDF XML</p>
<p>The parameter 'resultFormat' must not be null or zero length</p>
<p>The parameter 'resultFormat' must be one of the following: <ul>
<li>RS_XML</li>
<li>RS_TEXT</li>
<li>RS_RDF/N3</li>
<li>RS_JSON</li>
<li>RS_RDF</li>
</ul>
</p>
--%>
</div><!-- content -->
</body></html>

View file

@ -0,0 +1,12 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<h3>SPARQL Update Test</h3>
<p>This is an expermental SPARQL update service.</p>
<form action="${urls.base}/sparqlUpdateTest" method="post">
<p>
<textarea name="update" rows="20" cols="80" ></textarea>
<input type="submit" />
</p>
</form>