diff --git a/webapp/config/licenser/known_exceptions.txt b/webapp/config/licenser/known_exceptions.txt index 2551ba6f7..6efdabf02 100644 --- a/webapp/config/licenser/known_exceptions.txt +++ b/webapp/config/licenser/known_exceptions.txt @@ -165,6 +165,9 @@ webapp/web/js/raphael/* # See /doc/3rd-party-licenses.txt for LICENSE file webapp/web/js/sparql/prototype.js +# See /doc/3rd-party-licenses.txt for LICENSE file +webapp/web/js/amplify/amplify.store.min.js + # Apache Solr search platform. See /doc/3rd-party-licenses.txt for LICENSE file solr/**/* solr/* diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ApplicationBean.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ApplicationBean.java index bcf83a979..99dec7616 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ApplicationBean.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ApplicationBean.java @@ -49,15 +49,6 @@ public class ApplicationBean { private String copyrightAnchor; private String themeDir; - public static ApplicationBean getAppBean(ServletContext sc){ - if( sc != null ){ - Object obj = sc.getAttribute("applicationBean"); - if( obj != null ) - return (ApplicationBean)obj; - } - return new ApplicationBean(); - } - public String toString() { String output = "Application Bean Contents:\n"; output += " initialized from DB: [" + initialized + "]\n"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java index da86839ca..6d85141e2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/OntologyController.java @@ -33,9 +33,6 @@ import edu.cornell.mannlib.vitro.webapp.web.ContentType; public class OntologyController extends VitroHttpServlet{ private static final Log log = LogFactory.getLog(OntologyController.class.getName()); - private String default_jsp = Controllers.BASIC_JSP; - private ApplicationBean appBean; - public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{ doGet(request, response); @@ -242,7 +239,7 @@ public class OntologyController extends VitroHttpServlet{ throws IOException, ServletException { VitroRequest vreq = new VitroRequest(req); - ApplicationBean appBean = ApplicationBean.getAppBean(getServletContext()); + ApplicationBean appBean = vreq.getAppBean(); //set title before we do the highlighting so we don't get markup in it. req.setAttribute("title","not found"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index 7e67e0886..88416f911 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -283,12 +283,8 @@ public class VitroRequest extends HttpServletRequestWrapper { } public ApplicationBean getAppBean(){ - //return (ApplicationBean) getAttribute("appBean"); return getWebappDaoFactory().getApplicationDao().getApplicationBean(); } - public void setAppBean(ApplicationBean ab){ - setAttribute("appBean",ab); - } @SuppressWarnings("unchecked") @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/StartupStatusController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/StartupStatusController.java index 2b5866b5a..fb587eb20 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/StartupStatusController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/admin/StartupStatusController.java @@ -7,7 +7,6 @@ import java.util.Map; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; -import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; @@ -31,7 +30,7 @@ public class StartupStatusController extends FreemarkerHttpServlet { body.put("title", "Startup Status"); body.put("status", StartupStatus.getBean(getServletContext())); body.put("contextPath", getContextPath()); - body.put("applicationName", getApplicationName()); + body.put("applicationName", getApplicationName(vreq)); return new TemplateResponseValues("startupStatus-display.ftl", body); } @@ -45,11 +44,10 @@ public class StartupStatusController extends FreemarkerHttpServlet { } } - private Object getApplicationName() { + private Object getApplicationName(VitroRequest vreq) { String name = ""; try { - ApplicationBean app = ApplicationBean.getAppBean(getServletContext()); - name = app.getApplicationName(); + name = vreq.getAppBean().getApplicationName(); } catch (Exception e) { // deal with problems below } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContext.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContext.java index f822360cc..96300bbad 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContext.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContext.java @@ -15,12 +15,6 @@ public interface IndividualRequestAnalysisContext { */ String getDefaultNamespace(); - /** - * Is there a namespace for this prefix? If not, return an empty string, but - * never null. - */ - String getNamespaceForPrefix(String prefix); - /** * Use the IndividualDao to get this individual. * diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextImpl.java index 2198c89f5..5f3ebc7e4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextImpl.java @@ -15,8 +15,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; -import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; -import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; /** * Implement all of the fiddly-bits that we need for analyzing the request for @@ -45,25 +43,6 @@ public class IndividualRequestAnalysisContextImpl implements return wadf.getDefaultNamespace(); } - @Override - public String getNamespaceForPrefix(String prefix) { - if (prefix == null) { - return ""; - } - - NamespaceMapper namespaceMapper = NamespaceMapperFactory - .getNamespaceMapper(ctx); - if (namespaceMapper == null) { - log.warn("No NamespaceMapper in ServletContext. Request URL was '" - + vreq.getRequestURL() + "'"); - return ""; - } - - String ns = namespaceMapper.getNamespaceForPrefix(prefix); - - return (ns == null) ? "" : ns; - } - @Override public Individual getIndividualByURI(String individualUri) { if (individualUri == null) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java index 2d5bad4a3..3b3c6d091 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzer.java @@ -30,7 +30,6 @@ public class IndividualRequestAnalyzer { private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]+)/\\1\\.(rdf|n3|ttl)$"); private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]+)$"); private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]+)$"); - private static Pattern NS_PREFIX_URL = Pattern.compile("^/individual/([^/]*)/([^/]+)$"); private final VitroRequest vreq; private final IndividualRequestAnalysisContext analysisContext; @@ -164,7 +163,6 @@ public class IndividualRequestAnalyzer { * /individual/localname/localname.rdf * /individual/localname/localname.n3 * /individual/localname/localname.ttl - * /individual/nsprefix/localname * * * @return null on failure. @@ -202,14 +200,6 @@ public class IndividualRequestAnalyzer { return getIndividualByLocalname(rdfMatch.group(1)); } - // Does the URL look like a namespace prefix followed by a local - // name? - Matcher prefix_match = NS_PREFIX_URL.matcher(url); - if (prefix_match.matches() && prefix_match.groupCount() == 2) { - return getIndividualByPrefixAndLocalname(prefix_match.group(1), - prefix_match.group(2)); - } - // Couldn't match it to anything. return null; } catch (Throwable e) { @@ -299,12 +289,6 @@ public class IndividualRequestAnalyzer { return getIndividualByUri(uri); } - private Individual getIndividualByPrefixAndLocalname(String prefix, - String localName) { - String ns = analysisContext.getNamespaceForPrefix(prefix); - return getIndividualByUri(ns + localName); - } - private Individual getIndividualByNetId(String netId) { return analysisContext.getIndividualByNetId(netId); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DateTimeValueFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DateTimeValueFormGenerator.java index f6d97b2e6..ebb7b298e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DateTimeValueFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DateTimeValueFormGenerator.java @@ -27,7 +27,7 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator { final static String vivoCore = "http://vivoweb.org/ontology/core#"; - final static String toDateTimeValue = vivoCore + "dateTimeValue"; + final String toDateTimeValue = vivoCore + "dateTimeValue"; final static String valueType = vivoCore + "DateTimeValue"; final static String dateTimeValue = vivoCore + "dateTime"; final static String dateTimePrecision = vivoCore + "dateTimePrecision"; @@ -41,23 +41,23 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator initPropertyParameters(vreq, session, conf); initObjectPropForm(conf, vreq); - conf.setTemplate("dateTimeValueForm.ftl"); + conf.setTemplate(this.getTemplate()); conf.setVarNameForSubject("subject"); conf.setVarNameForPredicate("toDateTimeValue"); conf.setVarNameForObject("valueNode"); - conf.setN3Optional(Arrays.asList(n3ForValue)); + conf.setN3Optional(Arrays.asList(getN3ForValue())); conf.addNewResource("valueNode", DEFAULT_NS_FOR_NEW_RESOURCE); conf.addSparqlForExistingLiteral( - "dateTimeField-value", existingDateTimeValueQuery); + "dateTimeField-value", getExistingDateTimeValueQuery()); conf.addSparqlForExistingUris( - "dateTimeField-precision", existingPrecisionQuery); - conf.addSparqlForExistingUris("valueNode", existingNodeQuery); + "dateTimeField-precision", getExistingPrecisionQuery()); + conf.addSparqlForExistingUris("valueNode", getExistingNodeQuery()); - FieldVTwo dateTimeField = new FieldVTwo().setName("dateTimeField"); + FieldVTwo dateTimeField = new FieldVTwo().setName(this.getDateTimeFieldName()); dateTimeField.setEditElement(new DateTimeWithPrecisionVTwo(dateTimeField, VitroVocabulary.Precision.SECOND.uri(), VitroVocabulary.Precision.NONE.uri())); @@ -67,34 +67,40 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator //Adding additional data, specifically edit mode addFormSpecificData(conf, vreq); //prepare - prepare(vreq, conf); - return conf; - } + prepare(vreq, conf); + return conf; + } - final static String n3ForValue = - "?subject <" + toDateTimeValue + "> ?valueNode . \n" + + + //Writing these as methods instead of static strings allows the method getToDateTimeValuePredicate + //to be called after the class has been initialized - this is important for subclasses of this generator + //that rely on vreq for predicate + protected String getN3ForValue() { + return "?subject <" + this.getToDateTimeValuePredicate() + "> ?valueNode . \n" + "?valueNode a <" + valueType + "> . \n" + "?valueNode <" + dateTimeValue + "> ?dateTimeField-value . \n" + - "?valueNode <" + dateTimePrecision + "> ?dateTimeField-precision ."; + "?valueNode <" + dateTimePrecision + "> ?dateTimeField-precision ."; + } - final static String existingDateTimeValueQuery = - "SELECT ?existingDateTimeValue WHERE { \n" + - "?subject <" + toDateTimeValue + "> ?existingValueNode . \n" + + protected String getExistingDateTimeValueQuery () { + return "SELECT ?existingDateTimeValue WHERE { \n" + + "?subject <" + this.getToDateTimeValuePredicate() + "> ?existingValueNode . \n" + "?existingValueNode a <" + valueType + "> . \n" + "?existingValueNode <" + dateTimeValue + "> ?existingDateTimeValue }"; + } - final static String existingPrecisionQuery = - "SELECT ?existingPrecision WHERE { \n" + - "?subject <" + toDateTimeValue + "> ?existingValueNode . \n" + + protected String getExistingPrecisionQuery() { + return "SELECT ?existingPrecision WHERE { \n" + + "?subject <" + this.getToDateTimeValuePredicate() + "> ?existingValueNode . \n" + "?existingValueNode a <" + valueType + "> . \n" + "?existingValueNode <" + dateTimePrecision + "> ?existingPrecision }"; - - final static String existingNodeQuery = - "SELECT ?existingNode WHERE { \n" + - "?subject <" + toDateTimeValue + "> ?existingNode . \n" + + } + protected String getExistingNodeQuery() { + return "SELECT ?existingNode WHERE { \n" + + "?subject <" + this.getToDateTimeValuePredicate() + "> ?existingNode . \n" + "?existingNode a <" + valueType + "> }"; - + } public static String getNodeVar() { return "valueNode"; } @@ -103,6 +109,19 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator return "?" + getNodeVar(); } + //isolating the predicate in this fashion allows this class to be subclassed for other date time value + //properties + protected String getToDateTimeValuePredicate() { + return this.toDateTimeValue; + } + + protected String getDateTimeFieldName() { + return "dateTimeField"; + } + + protected String getTemplate() { + return "dateTimeValueForm.ftl"; + } //Adding form specific data such as edit mode public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { HashMap formSpecificData = new HashMap(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java index 53c30e304..388b71e38 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java @@ -94,6 +94,10 @@ public class FileServingServlet extends VitroHttpServlet { String actualFilename = findAndValidateFilename(fileInfo, path); in = openImageInputStream(fileInfo, actualFilename); + } catch (FileServingException e) { + log.info("Failed to serve the file at '" + path + "' -- " + e.getMessage()); + in = openMissingLinkImage(request); + mimeType = "image/png"; } catch (Exception e) { log.warn("Failed to serve the file at '" + path + "' -- " + e.getMessage()); in = openMissingLinkImage(request); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java index 4a145dc8d..3ef123eb4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java @@ -21,6 +21,8 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import freemarker.cache.WebappTemplateLoader; import freemarker.template.Configuration; @@ -67,36 +69,36 @@ public class StartupStatusDisplayFilter implements Filter { statusAlreadyDisplayed = true; } - private void displayStartupStatus(ServletRequest req, ServletResponse resp) throws IOException, - ServletException { - HttpServletResponse hResp = (HttpServletResponse) resp; + private void displayStartupStatus(ServletRequest req, ServletResponse resp) + throws IOException, ServletException { + HttpServletResponse hresp = (HttpServletResponse) resp; + HttpServletRequest hreq = (HttpServletRequest) req; try { Map bodyMap = new HashMap(); bodyMap.put("status", ss); bodyMap.put("showLink", !isFatal()); bodyMap.put("contextPath", getContextPath()); - bodyMap.put("applicationName", getApplicationName()); - - HttpServletRequest httpreq = (HttpServletRequest) req; - String url = ""; - - String path = httpreq.getRequestURI(); - if( path != null ){ - url = path; - } - - String query = httpreq.getQueryString(); - if( !StringUtils.isEmpty( query )){ - url = url + "?" + query; - } - - bodyMap.put("url", url ); + bodyMap.put("applicationName", getApplicationName()); - hResp.setContentType("text/html;charset=UTF-8"); - hResp.setStatus(SC_INTERNAL_SERVER_ERROR); + String url = ""; + + String path = hreq.getRequestURI(); + if (path != null) { + url = path; + } + + String query = hreq.getQueryString(); + if (!StringUtils.isEmpty(query)) { + url = url + "?" + query; + } + + bodyMap.put("url", url); + + hresp.setContentType("text/html;charset=UTF-8"); + hresp.setStatus(SC_INTERNAL_SERVER_ERROR); Template tpl = loadFreemarkerTemplate(); - tpl.process(bodyMap, hResp.getWriter()); + tpl.process(bodyMap, hresp.getWriter()); } catch (TemplateException e) { throw new ServletException("Problem with Freemarker Template", e); } @@ -114,7 +116,9 @@ public class StartupStatusDisplayFilter implements Filter { private Object getApplicationName() { String name = ""; try { - ApplicationBean app = ApplicationBean.getAppBean(ctx); + WebappDaoFactory wadf = (WebappDaoFactory) ctx + .getAttribute("webappDaoFactory"); + ApplicationBean app = wadf.getApplicationDao().getApplicationBean(); name = app.getApplicationName(); } catch (Exception e) { // deal with problems below diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index 02924963f..f1d7a6e71 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -38,7 +38,6 @@ 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.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; -import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -82,19 +81,10 @@ public class VitroRequestPrep implements Filter { }; private ServletContext _context; - private ApplicationBean _appbean; @Override public void init(FilterConfig filterConfig) throws ServletException { _context = filterConfig.getServletContext(); - - Object o = _context.getAttribute("applicationBean"); - if (o instanceof ApplicationBean) { - _appbean = (ApplicationBean) o; - } else { - _appbean = new ApplicationBean(); - } - log.debug("VitroRequestPrep: AppBean theme " + _appbean.getThemeDir()); } @Override @@ -132,9 +122,6 @@ public class VitroRequestPrep implements Filter { VitroRequest vreq = new VitroRequest(req); - //-- setup appBean --// - vreq.setAppBean(_appbean); - //-- setup DAO factory --// WebappDaoFactory wdf = getWebappDaoFactory(vreq); //TODO: get accept-language from request and set as preferred languages diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzerTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzerTest.java index 709e72365..eca94a2f4 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzerTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalyzerTest.java @@ -52,15 +52,6 @@ public class IndividualRequestAnalyzerTest extends AbstractTestClass { private static final String URL_BYTESTREAM_ALIAS = URL_HOME_PAGE + "/file/" + ID_FILE_BYTESTREAM + "/" + BYTESTREAM_FILENAME; - /** - * Info about an individual that appears in a different namespace. - */ - private static final String SOME_PREFIX = "somePrefix"; - private static final String SOME_NAMESPACE = "http://some.namespace/"; - private static final String ID_INDIVIDUAL_FOREIGN = "foreignId"; - private static final String URI_INDIVIDUAL_FOREIGN = SOME_NAMESPACE - + ID_INDIVIDUAL_FOREIGN; - private IndividualRequestAnalyzer analyzer; private IndividualRequestAnalysisContextStub analysisContext; private HttpServletRequestStub req; @@ -69,7 +60,6 @@ public class IndividualRequestAnalyzerTest extends AbstractTestClass { private IndividualStub testIndividual; private IndividualStub bytestreamIndividual; - private IndividualStub foreignIndividual; @Before public void setup() { @@ -83,10 +73,6 @@ public class IndividualRequestAnalyzerTest extends AbstractTestClass { bytestreamIndividual = new IndividualStub(URI_FILE_BYTESTREAM); analysisContext.addIndividual(bytestreamIndividual); analysisContext.setAliasUrl(URI_FILE_BYTESTREAM, URL_BYTESTREAM_ALIAS); - - foreignIndividual = new IndividualStub(URI_INDIVIDUAL_FOREIGN); - analysisContext.addIndividual(foreignIndividual); - analysisContext.setNamespacePrefix(SOME_PREFIX, SOME_NAMESPACE); } // ---------------------------------------------------------------------- @@ -132,16 +118,6 @@ public class IndividualRequestAnalyzerTest extends AbstractTestClass { assertDefaultRequestInfo("find by display path", URI_INDIVIDUAL_TEST); } - /** /individual/nsPrefix/localname */ - @Test - public void findByPrefixAndLocalname() { - req.setRequestUrl(url(DEFAULT_NAMESPACE + SOME_PREFIX + "/" - + ID_INDIVIDUAL_FOREIGN)); - analyzeIt(); - assertDefaultRequestInfo("find by prefix and localname", - URI_INDIVIDUAL_FOREIGN); - } - /** /individual/a/b/c fails. */ @Test public void unrecognizedPath() { diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextStub.java index d303956b2..2adc18ee7 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualRequestAnalysisContextStub.java @@ -21,7 +21,6 @@ public class IndividualRequestAnalysisContextStub implements private final String defaultNamespace; private final Map individualsByUri = new HashMap(); private final Map profilePages = new HashMap(); - private final Map namespacesByPrefix = new HashMap(); private final Map aliasUrlsByIndividual = new HashMap(); public IndividualRequestAnalysisContextStub(String defaultNamespace) { @@ -36,10 +35,6 @@ public class IndividualRequestAnalysisContextStub implements profilePages.put(netId, individual); } - public void setNamespacePrefix(String prefix, String namespace) { - namespacesByPrefix.put(prefix, namespace); - } - public void setAliasUrl(String individualUri, String aliasUrl) { aliasUrlsByIndividual.put(individualUri, aliasUrl); } @@ -53,15 +48,6 @@ public class IndividualRequestAnalysisContextStub implements return defaultNamespace; } - @Override - public String getNamespaceForPrefix(String prefix) { - if (prefix == null) { - return ""; - } - String namespace = namespacesByPrefix.get(prefix); - return (namespace == null) ? "" : namespace; - } - @Override public Individual getIndividualByURI(String individualUri) { if (individualUri == null) { diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/utils/NamespaceMapperStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/utils/NamespaceMapperStub.java deleted file mode 100644 index 5995d57e3..000000000 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/utils/NamespaceMapperStub.java +++ /dev/null @@ -1,123 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package stubs.edu.cornell.mannlib.vitro.webapp.utils; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; - -import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; - -/** - * A minimal implementation of the NamespaceMapper. - * - * I have only implemented the methods that I needed. Feel free to implement - * others. - */ -public class NamespaceMapperStub implements NamespaceMapper { - // ---------------------------------------------------------------------- - // Stub infrastructure - // ---------------------------------------------------------------------- - - private final Map prefixMap = new HashMap(); - - public void setPrefixForNamespace(String prefix, String namespace) { - prefixMap.put(prefix, namespace); - } - - // ---------------------------------------------------------------------- - // Stub methods - // ---------------------------------------------------------------------- - - @Override - public String getNamespaceForPrefix(String prefix) { - return prefixMap.get(prefix); - } - - // ---------------------------------------------------------------------- - // Un-implemented methods - // ---------------------------------------------------------------------- - - @Override - public void addedStatement(Statement arg0) { - throw new RuntimeException( - "NamespaceMapperStub.addedStatement() not implemented."); - } - - @Override - public void addedStatements(Statement[] arg0) { - throw new RuntimeException( - "NamespaceMapperStub.addedStatements() not implemented."); - } - - @Override - public void addedStatements(List arg0) { - throw new RuntimeException( - "NamespaceMapperStub.addedStatements() not implemented."); - } - - @Override - public void addedStatements(StmtIterator arg0) { - throw new RuntimeException( - "NamespaceMapperStub.addedStatements() not implemented."); - } - - @Override - public void addedStatements(Model arg0) { - throw new RuntimeException( - "NamespaceMapperStub.addedStatements() not implemented."); - } - - @Override - public void notifyEvent(Model arg0, Object arg1) { - throw new RuntimeException( - "NamespaceMapperStub.notifyEvent() not implemented."); - } - - @Override - public void removedStatement(Statement arg0) { - throw new RuntimeException( - "NamespaceMapperStub.removedStatement() not implemented."); - } - - @Override - public void removedStatements(Statement[] arg0) { - throw new RuntimeException( - "NamespaceMapperStub.removedStatements() not implemented."); - } - - @Override - public void removedStatements(List arg0) { - throw new RuntimeException( - "NamespaceMapperStub.removedStatements() not implemented."); - } - - @Override - public void removedStatements(StmtIterator arg0) { - throw new RuntimeException( - "NamespaceMapperStub.removedStatements() not implemented."); - } - - @Override - public void removedStatements(Model arg0) { - throw new RuntimeException( - "NamespaceMapperStub.removedStatements() not implemented."); - } - - @Override - public String getPrefixForNamespace(String namespace) { - throw new RuntimeException( - "NamespaceMapperStub.getPrefixForNamespace() not implemented."); - } - - @Override - public List getPrefixesForNamespace(String namespace) { - throw new RuntimeException( - "NamespaceMapperStub.getPrefixesForNamespace() not implemented."); - } - -} diff --git a/webapp/web/css/individual/individual-property-groups.css b/webapp/web/css/individual/individual-property-groups.css new file mode 100644 index 000000000..7edcb4011 --- /dev/null +++ b/webapp/web/css/individual/individual-property-groups.css @@ -0,0 +1,32 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +span#toggleContainer { + float:right; + padding:10px 8px 0 0; + font-size: 0.85em; +} +section.property-group h2 { + padding: 8px 10px 4px 12px; +} +.scroll-up { + position: absolute; + width: 21px; + height: 30px; + top: 8px; /* changed for redesign, was 0 */ + right: 12px; /* changed for redesign, was -21px;*/ +} +section.property-group div { + margin-top:15px; + display:none; +} +section.property-group h2 { + font-size: 1.15em !important; + color: #5e6363 !important; + font-weight: normal !important; + background: #fafaf9 !important; +} +/* this class is referenced in java script; the important is needed to override the color in the previous selector */ +section.property-group h2.expandedPropGroupH2 { + background:#e4ecf3 !important; + color:#2485ae !important; +} diff --git a/webapp/web/css/individual/individual.css b/webapp/web/css/individual/individual.css index 8f5e4764f..4e22cd6ad 100644 --- a/webapp/web/css/individual/individual.css +++ b/webapp/web/css/individual/individual.css @@ -32,7 +32,7 @@ /* <------ INDIVIDUAL INTRO FOR ANY CLASS*/ #individual-intro { margin-top: 15px; - margin-bottom: 20px; + margin-bottom: 0; position: relative; overflow: hidden; } @@ -63,7 +63,7 @@ img#uriIcon { width: 166px; float: left; padding-right: 1.5em; - margin-bottom: 20px; + margin-bottom: 0; } #share-contact h3 { margin-top: 15px; diff --git a/webapp/web/error.jsp b/webapp/web/error.jsp index 00622fc76..a429ebed2 100755 --- a/webapp/web/error.jsp +++ b/webapp/web/error.jsp @@ -13,7 +13,6 @@ request.setAttribute("bodyJsp", "/errorbody.jsp"); request.setAttribute("title", "Error"); request.setAttribute("css", ""); - request.setAttribute("appBean", appBean); request.setAttribute("themeDir", themeDir); %> diff --git a/webapp/web/images/individual/collapse-prop-group.png b/webapp/web/images/individual/collapse-prop-group.png new file mode 100644 index 000000000..fac863a85 Binary files /dev/null and b/webapp/web/images/individual/collapse-prop-group.png differ diff --git a/webapp/web/images/individual/expand-prop-group.png b/webapp/web/images/individual/expand-prop-group.png new file mode 100644 index 000000000..26b57a771 Binary files /dev/null and b/webapp/web/images/individual/expand-prop-group.png differ diff --git a/webapp/web/js/amplify/amplify.store.min.js b/webapp/web/js/amplify/amplify.store.min.js new file mode 100644 index 000000000..7bd55c9bf --- /dev/null +++ b/webapp/web/js/amplify/amplify.store.min.js @@ -0,0 +1,10 @@ +/*! + * Amplify Store - Persistent Client-Side Storage 1.1.0 + * + * Copyright 2011 appendTo LLC. (http://appendto.com/team) + * Dual licensed under the MIT or GPL licenses. + * http://appendto.com/open-source-licenses + * + * http://amplifyjs.com + */ +(function(a,b){function e(a,e){c.addType(a,function(f,g,h){var i,j,k,l,m=g,n=(new Date).getTime();if(!f){m={},l=[],k=0;try{f=e.length;while(f=e.key(k++))d.test(f)&&(j=JSON.parse(e.getItem(f)),j.expires&&j.expires<=n?l.push(f):m[f.replace(d,"")]=j.data);while(f=l.pop())e.removeItem(f)}catch(o){}return m}f="__amplify__"+f;if(g===b){i=e.getItem(f),j=i?JSON.parse(i):{expires:-1};if(j.expires&&j.expires<=n)e.removeItem(f);else return j.data}else if(g===null)e.removeItem(f);else{j=JSON.stringify({data:g,expires:h.expires?n+h.expires:null});try{e.setItem(f,j)}catch(o){c[a]();try{e.setItem(f,j)}catch(o){throw c.error()}}}return m})}var c=a.store=function(a,b,d,e){var e=c.type;d&&d.type&&d.type in c.types&&(e=d.type);return c.types[e](a,b,d||{})};c.types={},c.type=null,c.addType=function(a,b){c.type||(c.type=a),c.types[a]=b,c[a]=function(b,d,e){e=e||{},e.type=a;return c(b,d,e)}},c.error=function(){return"amplify.store quota exceeded"};var d=/^__amplify__/;for(var f in{localStorage:1,sessionStorage:1})try{window[f].getItem&&e(f,window[f])}catch(g){}if(window.globalStorage)try{e("globalStorage",window.globalStorage[window.location.hostname]),c.type==="sessionStorage"&&(c.type="globalStorage")}catch(g){}(function(){if(!c.types.localStorage){var a=document.createElement("div"),d="amplify";a.style.display="none",document.getElementsByTagName("head")[0].appendChild(a);try{a.addBehavior("#default#userdata"),a.load(d)}catch(e){a.parentNode.removeChild(a);return}c.addType("userData",function(e,f,g){a.load(d);var h,i,j,k,l,m=f,n=(new Date).getTime();if(!e){m={},l=[],k=0;while(h=a.XMLDocument.documentElement.attributes[k++])i=JSON.parse(h.value),i.expires&&i.expires<=n?l.push(h.name):m[h.name]=i.data;while(e=l.pop())a.removeAttribute(e);a.save(d);return m}e=e.replace(/[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g,"-");if(f===b){h=a.getAttribute(e),i=h?JSON.parse(h):{expires:-1};if(i.expires&&i.expires<=n)a.removeAttribute(e);else return i.data}else f===null?a.removeAttribute(e):(j=a.getAttribute(e),i=JSON.stringify({data:f,expires:g.expires?n+g.expires:null}),a.setAttribute(e,i));try{a.save(d)}catch(o){j===null?a.removeAttribute(e):a.setAttribute(e,j),c.userData();try{a.setAttribute(e,i),a.save(d)}catch(o){j===null?a.removeAttribute(e):a.setAttribute(e,j);throw c.error()}}return m})}})(),function(){function e(a){return a===b?b:JSON.parse(JSON.stringify(a))}var a={},d={};c.addType("memory",function(c,f,g){if(!c)return e(a);if(f===b)return e(a[c]);d[c]&&(clearTimeout(d[c]),delete d[c]);if(f===null){delete a[c];return null}a[c]=f,g.expires&&(d[c]=setTimeout(function(){delete a[c],delete d[c]},g.expires));return f})}()})(this.amplify=this.amplify||{}) \ No newline at end of file diff --git a/webapp/web/js/imageUpload/validateUpload.js b/webapp/web/js/imageUpload/validateUpload.js deleted file mode 100644 index d769d201a..000000000 --- a/webapp/web/js/imageUpload/validateUpload.js +++ /dev/null @@ -1,9 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -function validate_upload_file(form_passed){ - - if (form_passed.datafile.value == "") { - alert ("Please browse and select a photo"); - return false; - } -} diff --git a/webapp/web/js/individual/propertyGroupControls.js b/webapp/web/js/individual/propertyGroupControls.js new file mode 100644 index 000000000..95cd1644b --- /dev/null +++ b/webapp/web/js/individual/propertyGroupControls.js @@ -0,0 +1,115 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +$(document).ready(function(){ + + $.extend(this, individualLocalName); + + retrieveLocalStorage(); + + // expands/collapses the div within each property group + $.each($('section.property-group'), function() { + var groupName = $(this).attr("id"); + $(this).children("nav").children("img").click(function() { + if ( $("div[id='" + groupName + "Group']").is(":visible") ) { + $("div[id='" + groupName + "Group']").slideUp(222); + $(this).attr("src", $(this).attr("src").replace("collapse-prop-group","expand-prop-group")); + $("section#" + groupName).children("h2").removeClass("expandedPropGroupH2"); + } + else { + $("div[id='" + groupName + "Group']").slideDown(222); + $(this).attr("src", $(this).attr("src").replace("expand-prop-group","collapse-prop-group")); + $("section#" + groupName).children("h2").addClass("expandedPropGroupH2"); + } + manageLocalStorage(); + }); + }); + + + // expands/collapses all property groups together + $.each($('a#propertyGroupsToggle'), function() { + $('a#propertyGroupsToggle').click(function() { + var anchorHtml = $(this).html(); + if ( anchorHtml.indexOf('expand') > -1 ) { + $.each($('section.property-group'), function() { + $("div[id='" + $(this).attr("id") + "Group']").slideDown(222); + var innerSrc = $(this).children("nav").children("img").attr("src"); + $(this).children("nav").children("img").attr("src",innerSrc.replace("expand-prop-group","collapse-prop-group")); + $(this).children("h2").addClass("expandedPropGroupH2"); + }); + $(this).html("collapse all"); + } + else { + $.each($('section.property-group'), function() { + $("div[id='" + $(this).attr("id") + "Group']").slideUp(222); + var innerSrc = $(this).children("nav").children("img").attr("src"); + $(this).children("nav").children("img").attr("src",innerSrc.replace("collapse-prop-group","expand-prop-group")); + $(this).children("h2").removeClass("expandedPropGroupH2"); + }); + $(this).html("expand all"); + } + manageLocalStorage(); + }); + }); + + // Next two functions -- keep track of which property group tabs have been expanded, + // so if we return from a custom form or a related individual, even via the back button, + // the property groups will be expanded as before. + function manageLocalStorage() { + var localName = this.individualLocalName; + // is this individual already stored? If not, how many have been stored? + // If the answer is 3, remove the first one in before adding the new one + var current = amplify.store(localName); + var profiles = amplify.store("profiles"); + if ( current == undefined ) { + if ( profiles == undefined ) { + var lnArray = []; + lnArray.push(localName); + amplify.store("profiles", lnArray); + } + else if ( profiles != undefined && profiles.length >= 3 ) { + firstItem = profiles[0]; + amplify.store(firstItem, null); + profiles.splice(0,1); + profiles.push(localName); + amplify.store("profiles", profiles) + } + else if ( profiles != undefined && profiles.length < 3 ) { + profiles.push(localName); + amplify.store("profiles", profiles) + } + } + var groups = []; + $.each($('section.property-group').children("nav").children("img"), function() { + if ( $(this).attr('src').indexOf('collapse-prop-group') > -1 ) { + groups.push($(this).attr('groupName')); + } + }); + amplify.store(localName, groups); + var checkLength = amplify.store(localName); + if ( checkLength.length == 0 ) { + amplify.store(localName, null); + } + } + + function retrieveLocalStorage() { + var localName = this.individualLocalName; + var groups = amplify.store(individualLocalName); + if ( groups != undefined ) { + for ( i = 0; i < groups.length; i++) { + var groupName = groups[i]; + // unlikely, but it's possible a group that was previously opened and stored won't be displayed + // because the object properties would have been deleted. So ensure that the group in local + // storage has been rendered on the page. More likely, a user navigated from a quick view to a full + // profile, opened a group, then navigated back to the quick view where the group isn't rendered. + if ($("section#" + groupName).length ) { + $("div[id='" + groupName + "Group']").slideDown(1); + $("img[groupName='" + groupName + "']").attr("src", $("img[groupName='" + groupName + "']").attr("src").replace("expand-prop-group","collapse-prop-group")); + $("section#" + groupName).children("h2").addClass("expandedPropGroupH2"); + } + } + if ( groups.length == $('section.property-group').length ) { + $('a#propertyGroupsToggle').html('collapse all'); + } + } + } +}); diff --git a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl index 894c9cea4..5811a727f 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl @@ -49,10 +49,18 @@ <#assign nameForOtherGroup = "other"> <#-- used by both individual-propertyGroupMenu.ftl and individual-properties.ftl --> <#-- Property group menu --> -<#include "individual-propertyGroupMenu.ftl"> +<#-- With release 1.6 the property group is no longer used. The include statement + remains in the event a particular VIVO site still wants to use it with the new + collapsible groups. + + <#include "individual-propertyGroupMenu.ftl"> +--> <#-- Ontology properties --> <#include "individual-properties.ftl"> + <#assign rdfUrl = individual.rdfUrl> diff --git a/webapp/web/templates/freemarker/body/individual/individual.ftl b/webapp/web/templates/freemarker/body/individual/individual.ftl index 62d979b8e..c76ed4da5 100644 --- a/webapp/web/templates/freemarker/body/individual/individual.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual.ftl @@ -1,7 +1,27 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> -<#-- Default individual profile page template --> +<#-- Default VIVO individual profile page template (extends individual.ftl in vitro) --> <#include "individual-setup.ftl"> +<#import "lib-vivo-properties.ftl" as vp> -<#include "individual-vitro.ftl"> \ No newline at end of file +<#assign individualProductExtension> + <#-- Include for any class specific template additions --> + ${classSpecificExtension!} + <@vp.webpages propertyGroups editable /> + + <#include "individual-overview.ftl"> + + + + + +<#include "individual-vitro.ftl"> + +${stylesheets.add('', + '')} + +${headScripts.add('', + '')} +${scripts.add('', + '')} diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl index dd48a75ca..9f0a0e643 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl @@ -4,62 +4,81 @@ <#import "lib-properties.ftl" as p> <#assign subjectUri = individual.controlPanelUrl()?split("=") > + +<#if ( propertyGroups.all?size > 1 ) > + + expand all + +<#else> +


+ <#list propertyGroups.all as group> <#assign groupName = group.getName(nameForOtherGroup)> <#assign verbose = (verbosePropertySwitch.currentValue)!false> + <#if groupName?has_content> + <#--the function replaces spaces in the name with underscores, also called for the property group menu--> + <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) > + <#else> + <#assign groupName = "Properties"> + <#assign groupNameHtmlId = "properties" > + -
+
<#-- Display the group heading --> - <#if groupName?has_content> - <#--the function replaces spaces in the name with underscores, also called for the property group menu--> - <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >

${groupName?capitalize}

- <#else> -

Properties

- <#-- List the properties in the group --> - <#list group.properties as property> -
- <#-- Property display name --> - <#if property.localName == "authorInAuthorship" && editable > -

${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage publications - -

- <#elseif property.localName == "hasResearcherRole" && editable > -

${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage grants & projects - -

- <#elseif property.localName == "organizationForPosition" && editable > -

${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage affiliated people - -

- <#else> -

${property.name} <@p.addLink property editable /> <@p.verboseDisplay property />

- - <#-- List the statements for each property --> -
    - <#-- data property --> - <#if property.type == "data"> - <@p.dataPropertyList property editable /> - <#-- object property --> +
    + <#list group.properties as property> +
    + <#-- Property display name --> + <#if property.localName == "authorInAuthorship" && editable > +

    ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> + style="padding-top:10px" > + manage publications + +

    + <#elseif property.localName == "hasResearcherRole" && editable > +

    ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> + style="padding-top:10px" > + manage grants & projects + +

    + <#elseif property.localName == "organizationForPosition" && editable > +

    ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> + style="padding-top:10px" > + manage affiliated people + +

    <#else> - <@p.objectProperty property editable /> +

    ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property />

    -
-
- + <#-- List the statements for each property --> +
    + <#-- data property --> + <#if property.type == "data"> + <@p.dataPropertyList property editable /> + <#-- object property --> + <#else> + <@p.objectProperty property editable /> + +
+ + +
+ \ No newline at end of file diff --git a/webapp/web/templates/page/basicPage.jsp b/webapp/web/templates/page/basicPage.jsp index 4685288bc..07b328d72 100644 --- a/webapp/web/templates/page/basicPage.jsp +++ b/webapp/web/templates/page/basicPage.jsp @@ -38,9 +38,6 @@ if (request.getAttribute("css") == null){ e+="basicPage.jsp expects that request parameter 'css' be set to css to include in page.\n"; } - if( request.getAttribute("appBean") == null){ - e+="basicPage.jsp expects that request attribute 'appBean' be set.\n"; - } if( e.length() > 0 ){ throw new JspException(e); } diff --git a/webapp/web/templates/page/blankPage.jsp b/webapp/web/templates/page/blankPage.jsp index 62e65e0a7..9fec63cb2 100644 --- a/webapp/web/templates/page/blankPage.jsp +++ b/webapp/web/templates/page/blankPage.jsp @@ -31,9 +31,6 @@ if (request.getAttribute("css") == null){ e+="basicPage.jsp expects that request parameter 'css' be set to css to include in page.\n"; } - if( request.getAttribute("appBean") == null){ - e+="basicPage.jsp expects that request attribute 'appBean' be set.\n"; - } if( e.length() > 0 ){ throw new JspException(e); }