/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ package lucee.runtime.tag; import java.io.IOException; import java.util.Map; import java.util.TreeMap; import lucee.commons.lang.StringUtil; import lucee.runtime.exp.ApplicationException; import lucee.runtime.exp.PageException; import lucee.runtime.ext.tag.BodyTagTryCatchFinallyImpl; import lucee.runtime.op.Caster; /** * base class for both cfhtmlhead and cfhtmlbody */ public abstract class HtmlHeadBodyBase extends BodyTagTryCatchFinallyImpl { private final static String REQUEST_ATTRIBUTE_PREFIX = "REQUEST_ATTRIBUTE_IDMAP_"; /** * The text to add to the 'head' area of an HTML page. Everything inside the quotation marks is placed in the 'head' section */ protected String text = null; protected String variable = null; private String action = null; private String id = null; @Override public void release() { super.release(); text = null; variable = null; action = null; id = null; } public abstract String getTagName(); public abstract void actionAppend() throws IOException, ApplicationException; public abstract void actionFlush() throws IOException; public abstract void actionRead() throws IOException, PageException; public abstract void actionReset() throws IOException; public abstract void actionWrite() throws IOException, ApplicationException; /** * @param variable the variable to set */ public void setVariable(String variable) { this.variable = variable; } /** * @param action the action to set */ public void setAction(String action) { if (StringUtil.isEmpty(action, true)) return; this.action = action.trim().toLowerCase(); } /** * set the value text * The text to add to the 'head' area of an HTML page. Everything inside the quotation marks is * placed in the 'head' section * * @param text value to set */ public void setText(String text) { this.text = text; } public void setId(String id) { this.id = id; } @Override public int doStartTag() throws PageException { return EVAL_BODY_BUFFERED; } @Override public int doEndTag() throws PageException { processTag(); return SKIP_BODY; } @Override public int doAfterBody() throws PageException { if (StringUtil.isEmpty(text) && bodyContent != null) { text = bodyContent.getString(); } if(bodyContent!=null)bodyContent.clearBody(); return SKIP_BODY; } protected void processTag() throws PageException { try { if (StringUtil.isEmpty(action, true) || action.equals("append")) { required(getTagName(), "text", text); if (isValid()) actionAppend(); } else if (action.equals("reset")) { resetIdMap(); actionReset(); } else if (action.equals("write")) { required(getTagName(), "text", text); resetIdMap(); if (isValid()) // call isValid() to register the id if set actionWrite(); } else if (action.equals("read")) actionRead(); else if (action.equals("flush")) actionFlush(); else throw new ApplicationException("invalid value [" + action + "] for attribute action", "values for attribute action are:append,read,reset,write"); } catch (IOException e) { throw Caster.toPageException(e); } } /** * * @return - true if the id was not set or was set and was not used yet in the request. if it was not set -- register it for future calls of the tag */ protected boolean isValid() { if (StringUtil.isEmpty(id)) return true; Map m = getIdMap(); boolean result = !m.containsKey(id); if (!result) m.put(id, Boolean.TRUE); return result; } protected Map getIdMap() { String reqAttr = REQUEST_ATTRIBUTE_PREFIX + getTagName(); Map result = (Map)pageContext.getRequest().getAttribute(reqAttr); if (result == null) { result = new TreeMap(String.CASE_INSENSITIVE_ORDER); pageContext.getRequest().setAttribute(reqAttr, result); } return result; } protected void resetIdMap() { String reqAttr = REQUEST_ATTRIBUTE_PREFIX + getTagName(); pageContext.getRequest().setAttribute(reqAttr, null); } }