diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java index 77ffc1a20..34caa8c37 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualController.java @@ -92,7 +92,7 @@ public class IndividualController extends FreemarkerHttpServlet { String url = vreq.getRequestURI().substring(vreq.getContextPath().length()); // Check to see if the request is for a non-information resource, redirect if it is. - String redirectURL = checkForRedirect ( url, vreq.getHeader("accept") ); + String redirectURL = checkForRedirect ( url, vreq ); if( redirectURL != null ){ return new RedirectResponseValues(redirectURL); } @@ -108,7 +108,7 @@ public class IndividualController extends FreemarkerHttpServlet { return doNotFound(vreq); } - ContentType rdfFormat = checkForLinkedDataRequest(url,vreq.getHeader("accept")); + ContentType rdfFormat = checkForLinkedDataRequest(url, vreq); if( rdfFormat != null ){ return doRdf(vreq, individual, rdfFormat); } @@ -387,10 +387,10 @@ public class IndividualController extends FreemarkerHttpServlet { //Redirect if the request is for http://hostname/individual/localname // if accept is nothing or text/html redirect to ??? // if accept is some RDF thing redirect to the URL for RDF - private String checkForRedirect(String url, String acceptHeader) { + private String checkForRedirect(String url, VitroRequest vreq) { Matcher m = URI_PATTERN.matcher(url); if( m.matches() && m.groupCount() == 1 ){ - ContentType c = checkForLinkedDataRequest(url, acceptHeader); + ContentType c = checkForLinkedDataRequest(url, vreq); if( c != null ){ String redirectUrl = "/individual/" + m.group(1) + "/" + m.group(1) ; if( RDFXML_MIMETYPE.equals( c.getMediaType()) ){ @@ -413,13 +413,37 @@ public class IndividualController extends FreemarkerHttpServlet { private static Pattern TTL_REQUEST = Pattern.compile("^/individual/([^/]*)/\\1.ttl$"); private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]*)$"); + private static Pattern RDF_PARAM = Pattern.compile("rdf"); + private static Pattern N3_PARAM = Pattern.compile("n3"); + private static Pattern TTL_PARAM = Pattern.compile("ttl"); + /** * @return null if this is not a linked data request, returns content type if it is a * linked data request. */ - protected ContentType checkForLinkedDataRequest(String url, String acceptHeader) { + protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) { try { - //check the accept header + ContentType contentType = null; + Matcher m; + // Check for url param specifying format + String formatParam = (String) vreq.getParameter("format"); + if (formatParam != null) { + m = RDF_PARAM.matcher(formatParam); + if ( m.matches() ) { + return new ContentType(RDFXML_MIMETYPE); + } + m = N3_PARAM.matcher(formatParam); + if( m.matches() ) { + return new ContentType(N3_MIMETYPE); + } + m = TTL_PARAM.matcher(formatParam); + if( m.matches() ) { + return new ContentType(TTL_MIMETYPE); + } + } + + //check the accept header + String acceptHeader = vreq.getHeader("accept"); if (acceptHeader != null) { List actualContentTypes = new ArrayList(); actualContentTypes.add(new ContentType( XHTML_MIMETYPE )); @@ -428,14 +452,13 @@ public class IndividualController extends FreemarkerHttpServlet { actualContentTypes.add(new ContentType( RDFXML_MIMETYPE )); actualContentTypes.add(new ContentType( N3_MIMETYPE )); actualContentTypes.add(new ContentType( TTL_MIMETYPE )); - - - ContentType best = ContentType.getBestContentType(acceptHeader,actualContentTypes); - if (best!=null && ( - RDFXML_MIMETYPE.equals(best.getMediaType()) || - N3_MIMETYPE.equals(best.getMediaType()) || - TTL_MIMETYPE.equals(best.getMediaType()) )) - return best; + + contentType = ContentType.getBestContentType(acceptHeader,actualContentTypes); + if (contentType!=null && ( + RDFXML_MIMETYPE.equals(contentType.getMediaType()) || + N3_MIMETYPE.equals(contentType.getMediaType()) || + TTL_MIMETYPE.equals(contentType.getMediaType()) )) + return contentType; } /* @@ -444,22 +467,30 @@ public class IndividualController extends FreemarkerHttpServlet { http://vivo.cornell.edu/individual/n23/n23.n3 http://vivo.cornell.edu/individual/n23/n23.ttl */ - - Matcher m = RDF_REQUEST.matcher(url); - if( m.matches() ) - return new ContentType(RDFXML_MIMETYPE); - m = N3_REQUEST.matcher(url); - if( m.matches() ) - return new ContentType(N3_MIMETYPE); - m = TTL_REQUEST.matcher(url); - if( m.matches() ) - return new ContentType(TTL_MIMETYPE); + m = RDF_REQUEST.matcher(url); + if( m.matches() ) { + return new ContentType(RDFXML_MIMETYPE); + } + m = N3_REQUEST.matcher(url); + if( m.matches() ) { + return new ContentType(N3_MIMETYPE); + } + m = TTL_REQUEST.matcher(url); + if( m.matches() ) { + return new ContentType(TTL_MIMETYPE); + } + } catch (Throwable th) { log.error("problem while checking accept header " , th); } return null; } + + private ContentType getContentTypeFromString(String string) { + + return null; + } @SuppressWarnings("unused") private boolean checkForSunset(VitroRequest vreq, Individual entity) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java index ff1657046..30ceef439 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java @@ -234,12 +234,24 @@ public class UrlBuilder { } public static String getPath(String path, ParamMap params) { - String glue = "?"; - for (String key : params.keySet()) { - path += glue + key + "=" + urlEncode(params.get(key)); + return addParams(path, params, "?"); + } + + private static String addParams(String url, ParamMap params, String glue) { + for (String key: params.keySet()) { + url += glue + key + "=" + urlEncode(params.get(key)); glue = "&"; } - return path; + return url; + } + + public static String addParams(String url, ParamMap params) { + String glue = url.contains("?") ? "&" : "?"; + return addParams(url, params, glue); + } + + public static String addParams(String url, String...params) { + return addParams(url, new ParamMap(params)); } public static String getPath(Route route, ParamMap params) { @@ -267,8 +279,7 @@ public class UrlBuilder { if (defaultNamespace.equals(namespace)) { profileUrl = getUrl(Route.INDIVIDUAL.path() + "/" + localName); } else { - List externallyLinkedNamespaces = wadf.getApplicationDao().getExternallyLinkedNamespaces(); - if (externallyLinkedNamespaces.contains(namespace)) { + if (wadf.getApplicationDao().isExternallyLinkedNamespace(namespace)) { log.debug("Found externally linked namespace " + namespace); profileUrl = namespace + "/" + localName; } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ApplicationDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ApplicationDao.java index 6ccd29b4f..729865d2e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ApplicationDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ApplicationDao.java @@ -12,4 +12,6 @@ public interface ApplicationDao { public List getExternallyLinkedNamespaces(); + public boolean isExternallyLinkedNamespace(String namespace); + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ApplicationDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ApplicationDaoJena.java index 1b89dbc96..418240732 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ApplicationDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ApplicationDaoJena.java @@ -80,6 +80,11 @@ public class ApplicationDaoJena extends JenaBaseDao implements ApplicationDao { return externallyLinkedNamespaces; } + public boolean isExternallyLinkedNamespace(String namespace) { + List namespaces = getExternallyLinkedNamespaces(); + return namespaces.contains(namespace); + } + private class ExternalNamespacesChangeListener extends StatementListener { @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java index df3be635d..99282f914 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java @@ -2,15 +2,15 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; -import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.openrdf.model.URI; +import org.openrdf.model.impl.URIImpl; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.Link; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; @@ -86,10 +86,32 @@ public class IndividualTemplateModel extends BaseTemplateModel { return uri.startsWith(defaultNamespace) ? uri + "/" + getLocalName() + ".rdf" : null; } - // RY Used for the rdf link on the individual page. Is it correct that this is not the same - // as getLinkedDataUrl()? + // Used to create a link to a display of the individual's rdf. public String getRdfUrl() { - return getProfileUrl() + "/" + getLocalName() + ".rdf"; + + String individualUri = getUri(); + String profileUrl = getProfileUrl(); + + URI uri = new URIImpl(individualUri); + String namespace = uri.getNamespace(); + + // Individuals in the default namespace + // e.g., http://vivo.cornell.edu/individual/n2345/n2345.rdf + // where default namespace = http://vivo.cornell.edu/individual/ + String defaultNamespace = vreq.getWebappDaoFactory().getDefaultNamespace(); + if (defaultNamespace.equals(namespace)) { + return profileUrl + "/" + getLocalName() + ".rdf"; + } + + // An RDF url is not defined for an externally linked namespace. The data does not reside + // in the current system, and the external system may not accept a request for rdf. + if (vreq.getWebappDaoFactory().getApplicationDao().isExternallyLinkedNamespace(namespace)) { + return null; + } + + // http://some.other.namespace/n2345?format=application/rdf+xml + return UrlBuilder.addParams(profileUrl, "format", "rdf"); + } public String getEditUrl() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 750e93d11..8147cc6c0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -141,7 +141,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel try { return new CollatedObjectPropertyTemplateModel(op, subject, vreq, policyHelper); } catch (InvalidConfigurationException e) { - log.warn(e); + log.warn(e.getMessage()); return new UncollatedObjectPropertyTemplateModel(op, subject, vreq, policyHelper); } } else {