/* * #! * Ontopia Navigator * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.nav2.taglibs.tolog; import java.io.IOException; import java.util.Collection; import java.util.Collections; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.tagext.TagSupport; import net.ontopia.topicmaps.nav2.core.NavigatorRuntimeException; import net.ontopia.topicmaps.nav2.core.VariableNotSetException; import net.ontopia.topicmaps.nav2.impl.framework.InteractionELSupport; import net.ontopia.topicmaps.nav2.taglibs.logic.ContextTag; import net.ontopia.topicmaps.nav2.utils.FrameworkUtils; import net.ontopia.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * INTERNAL: Abstract super-class of an Output-Producing Tag. */ public abstract class BaseOutputProducingTag extends TagSupport { // initialization of logging facility private static Logger log = LoggerFactory .getLogger(BaseOutputProducingTag.class.getName()); // members protected boolean escapeEntities; // tag attributes protected String variableName; protected String query; protected String fallbackValue; protected abstract String getName(); public BaseOutputProducingTag() { this(true); } protected BaseOutputProducingTag(boolean escapeEntities) { log.debug("Constructing"); // Whether the generated String should be escaped to care about // HTML/XML entities or not. this.escapeEntities = escapeEntities; } /** * Process the start tag for this instance. */ public int doStartTag() throws JspTagException { try { Object outObject = generateOutputObject(); JspWriter out = pageContext.getOut(); generateOutput(out, outObject); } catch (IOException ioe) { String msg = "Error in " + getName() + ": " + ioe.getMessage(); log.error(msg); throw new NavigatorRuntimeException(msg, ioe); } return SKIP_BODY; } public final int doEndTag() { return EVAL_PAGE; } /** * reset the state of the Tag. */ public void release() { } public abstract void generateOutput(JspWriter out, Object outObject) throws JspTagException, IOException; /** * Get the object to write out (either through a variable or query). */ public Object generateOutputObject() throws JspTagException { if (query == null && variableName == null) throw new NavigatorRuntimeException(getName() + " : requires" + " either a 'query' - or a 'var' parameter, but got" + " neither.\n"); if (variableName != null && query != null) throw new NavigatorRuntimeException(getName() + " : requires" + " either a 'query' - or a 'var' parameter, but got both.\n"); Object outObject; if (variableName != null) { // This BaseOutputProducingTag should produce output from a variable. Collection coll = null; try { ContextTag contextTag = FrameworkUtils.getContextTag(pageContext); if (contextTag == null) throw new JspTagException("<tolog:*> tags must be nested directly or" + " indirectly within a <tolog:context> tag, but no" + " <tolog:context> was found."); coll = contextTag.getContextManager().getValue(variableName); } catch (VariableNotSetException e) { log.debug("didn't find " + variableName + ". Lookup in pageContext."); Object pageContextValue = InteractionELSupport .getValue(variableName, pageContext); if (pageContextValue == null) throw new NavigatorRuntimeException(getName() + " :" + " The variable '" + variableName + "' is not set, and hence cannot be referenced.\n"); coll = Collections.singleton(pageContextValue); } if (coll.isEmpty()) { if (fallbackValue == null) { throw new NavigatorRuntimeException(getName() + " : requires" + " a variable (attribute 'var') containing a non-empty" + " Collection, but the Collection in the variable '" + variableName + "' is empty. It is possible to get a" + " fallback value by setting the 'fallback' attribute.\n"); } else { return fallbackValue; } } outObject = coll.iterator().next(); // outObject contains the element of the input variable. } else { // query != null must be true. QueryWrapper queryWrapper = new QueryWrapper(pageContext, query); if (!queryWrapper.hasNext()) { if (fallbackValue == null) { throw new NavigatorRuntimeException(getName() + " :" + " requires a query result of at least one row, but got an" + " empty result set. It is possible to get a fallback value" + " by setting the 'fallback' attribute.\n"); } else { return fallbackValue; } } queryWrapper.next(); Object firstRow[] = queryWrapper.getCurrentRow(); if (firstRow.length != 1) throw new NavigatorRuntimeException(getName() + " :" + " requires a query result of 1 column, but got " + firstRow.length + " columns.\n"); outObject = firstRow[0]; // outObject contains the first (and only) column of the first row // of the query result. } return outObject; } // ----------------------------------------------------------------- // set methods // ----------------------------------------------------------------- public void setQuery(String query) { this.query = query; } public final void setVar(String variableName) { this.variableName = variableName; } public final void setFallback(String fallbackValue) { this.fallbackValue = fallbackValue; } // ----------------------------------------------------------------- // internal methods // ----------------------------------------------------------------- /** * INTERNAL: prints out string to specified JspWriter object * with respect if the entities should be escaped. */ protected final void print2Writer(JspWriter out, String string) throws IOException { if (escapeEntities) StringUtils.escapeHTMLEntities(string, out); else out.print( string ); } }