/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.tag; // Java 2 enterprise packages import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.log4j.Logger; import org.w3c.dom.Document; /** * Retrieves an answer to a query from a statement. * * @created 2001-11-19 * * @author Tom Adams * * @version $Revision: 1.9 $ * * @modified $Date: 2005/01/05 04:59:09 $ by $Author: newmana $ * * @company <a href="mailto:info@PIsoftware.com">Plugged In Software</a> * * @copyright ©2001 <a href="http://www.pisoftware.com/">Plugged In * Software Pty Ltd</a> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class AnswerTag extends BodyTagSupport { private static final long serialVersionUID = 3726055494484378655L; /** * variables to have page scope */ protected final static String PAGE_SCOPE = "page"; /** * variables to have request scope */ protected final static String REQUEST_SCOPE = "request"; /** * variables to have session scope */ protected final static String SESSION_SCOPE = "session"; /** * variables to have application scope */ protected final static String APPLICATION_SCOPE = "application"; /** * the name of the id attribute */ protected final static String ATTR_ID = "id"; /** * the name of the statement attribute */ protected final static String ATTR_STATEMENT = "statement"; /** * the name of the query attribute */ protected final static String ATTR_QUERY = "query"; /** * the name of the scope attribute */ protected final static String ATTR_SCOPE = "scope"; // // Constants // /** * the category to log to */ private final static Logger log = Logger.getLogger(AnswerTag.class.getName()); // // Members // /** * the id of the statement to retrieve answers from * */ private String statement = null; /** * the id of the query to retrieve the answer for * */ private String query = null; /** * the scope to create the tag variables in * */ private String scope = null; /** * the answers to the specified statement * */ private ArrayList<Document> answers = null; /** * the mapping of query ids to answer list indices * */ private HashMap<String,Integer> answerPositionMap = null; // release() // // Public API // /** * Sets the id of the statement to retrieve answers from. * * @param statement the id of the statement to retrieve answers from */ public void setStatement(String statement) { this.statement = statement; } // getStatement() /** * Sets the id of the query to retrieve the answer for. * * @param query the id of the query to retrieve the answer for */ public void setQuery(String query) { this.query = query; } // getQuery() /** * Sets the scope to create the tag variables in. * * @param scope the scope to create the tag variables in */ public void setScope(String scope) { this.scope = scope; } // setStatement() /** * Returns the id of the statement to retrieve answers from. * * @return the id of the statement to retrieve answers from */ public String getStatement() { return this.statement; } // setQuery() /** * Returns the id of the query to retrieve the answer for. * * @return the id of the query to retrieve the answer for */ public String getQuery() { return this.query; } // setScope() /** * Returns the scope to create the tag variables in. * * @return the scope to create the tag variables in */ public String getScope() { return this.scope; } // // Methods overriding BodyTagSupport // /** * @return a response code informing the servlet container how to proceed with * JSP tag execution * @throws JspException * @throws JspTagException EXCEPTION TO DO */ @SuppressWarnings("unchecked") public int doStartTag() throws JspTagException { // log that we're starting execution of the start tag log.debug("Starting answer tag execution"); // make sure that a statement has been specified if ( (this.getStatement() == null) || this.getStatement().equals("")) { throw new JspTagException("answer: Must contain a statement attribute."); } // end if // log that we've verified required attributes log.debug("Verified that statement attribute was set"); // make sure that a query has been specified if ( (this.getQuery() == null) || this.getQuery().equals("")) { throw new JspTagException("answer: Must contain a query attribute."); } // end if // log that we've verified required attributes log.debug("Verified that query attribute was set"); // get the list of answers ArrayList<Document> answers = (ArrayList<Document>)this.pageContext.getAttribute(this.getStatement()); if (answers == null) { throw new JspTagException("answer: No answers where found for the " + "statement with id " + this.getStatement()); } // end if // set the answers this.answers = answers; // log that we've found the answers log.debug("Found " + answers.size() + " answers in the specified statement"); // get mapping of answer positions HashMap<String, Integer> answerPositions = (HashMap<String, Integer>)this.pageContext.getAttribute(StatementTag. KEY_STATEMENT_PREFIX + "." + this.getStatement()); if (answerPositions == null) { throw new JspTagException("answer: No answer list mapping found for " + "statement with id " + this.getStatement()); } // end if // add the answer position map this.answerPositionMap = answerPositions; // log that we've found the position map log.debug("Found query answers position map from specified statement " + "tag containing " + answerPositions.size() + " query id mappings"); // continue to evaluate the body return EVAL_BODY_BUFFERED; } // doStartTag() /** * Returns the results of the nested queries. * * @return RETURNED VALUE TO DO * @throws JspTagException if an the content cannot be rendered */ public int doAfterBody() throws JspTagException { // log what we're doing log.debug("Returning query results"); try { // find out the position of the answer to the query Integer position = this.answerPositionMap.get(this.getQuery()); // only continue of we found its position (ie. there is an answer to // this query) if (position != null) { // get the answer to the query Document answer = this.answers.get(position.intValue()); // log that we've found an answer log.debug("Found answer to specified query"); // find out whether to return the answer to the stream or as a Document if (this.getId() != null) { // log that we're parsing results log.debug("Returning query answer as Document"); // set a page context variable containing the query answer this.pageContext.setAttribute(this.getId(), answer, this.getVariableScope()); } else { // log that we're returning the results to the stream log.debug("Returning raw answer to stream"); // get the null transformer (performs a straight copy) TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); // write the answer to a tmp buffer ByteArrayOutputStream out = new ByteArrayOutputStream(); transformer.transform(new DOMSource(answer), new StreamResult(out)); // write the buffer to the output stream this.getPreviousOut().println(out.toString()); log.debug("Successfully wrote raw answer to stream"); } // end if } else { // log that we found no answer log.debug("No answer found to specified query"); } // end if } catch (IOException ioe) { // log the error log.error("Error handling answer", ioe); // wrap it and re-throw! throw new JspTagException("answer: Unable to print query answer " + "to JSP output stream"); } catch (TransformerException te) { // log the error log.error("Error handling answer", te); // wrap it and re-throw! throw new JspTagException("answer: Unable to print query answer " + "to JSP output stream"); } catch (Exception e) { log.error("Unhandled exception in answers tag", e); } // try-catch // no need to re-execute the body return SKIP_BODY; } // doAfterBody() /** * Resets the tag to its default state. * */ public void release() { this.id = null; this.statement = null; this.query = null; this.scope = null; this.answers = null; this.answerPositionMap = null; } // getVariableScope() /** * Returns the scope to create the variables in (as a PageContext constant). * * @return the scope to create the variables in */ private int getVariableScope() { // get the scope specified as a tag attribute String requestedScope = this.getScope(); // default to page scope int scope = PageContext.PAGE_SCOPE; if ( (requestedScope == null) || requestedScope.equalsIgnoreCase("")) { scope = PageContext.PAGE_SCOPE; } else if (requestedScope.equalsIgnoreCase(PAGE_SCOPE)) { scope = PageContext.PAGE_SCOPE; } else if (requestedScope.equalsIgnoreCase(REQUEST_SCOPE)) { scope = PageContext.REQUEST_SCOPE; } else if (requestedScope.equalsIgnoreCase(SESSION_SCOPE)) { scope = PageContext.SESSION_SCOPE; } else if (requestedScope.equalsIgnoreCase(APPLICATION_SCOPE)) { scope = PageContext.APPLICATION_SCOPE; } // end if // return the scope return scope; } // getAnswerPositionMap() }