001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.tag; 020 021import java.io.IOException; 022import java.util.Map; 023import java.util.TreeMap; 024 025import lucee.commons.lang.StringUtil; 026import lucee.runtime.exp.ApplicationException; 027import lucee.runtime.exp.PageException; 028import lucee.runtime.ext.tag.BodyTagTryCatchFinallyImpl; 029import lucee.runtime.op.Caster; 030 031/** 032 * base class for both cfhtmlhead and cfhtmlbody 033 */ 034public abstract class HtmlHeadBodyBase extends BodyTagTryCatchFinallyImpl { 035 036 private final static String REQUEST_ATTRIBUTE_PREFIX = "REQUEST_ATTRIBUTE_IDMAP_"; 037 038 /** 039 * The text to add to the 'head' area of an HTML page. Everything inside the quotation marks is placed in the 'head' section 040 */ 041 protected String text = null; 042 protected String variable = null; 043 044 private String action = null; 045 private String id = null; 046 047 @Override 048 public void release() { 049 super.release(); 050 text = null; 051 variable = null; 052 action = null; 053 id = null; 054 } 055 056 public abstract String getTagName(); 057 public abstract void actionAppend() throws IOException, ApplicationException; 058 public abstract void actionFlush() throws IOException; 059 public abstract void actionRead() throws IOException, PageException; 060 public abstract void actionReset() throws IOException; 061 public abstract void actionWrite() throws IOException, ApplicationException; 062 063 /** 064 * @param variable the variable to set 065 */ 066 public void setVariable(String variable) { 067 this.variable = variable; 068 } 069 070 /** 071 * @param action the action to set 072 */ 073 public void setAction(String action) { 074 if (!StringUtil.isEmpty(action, true)) 075 this.action = action.trim().toLowerCase(); 076 } 077 078 079 /** 080 * set the value text 081 * The text to add to the 'head' area of an HTML page. Everything inside the quotation marks is 082 * placed in the 'head' section 083 * 084 * @param text value to set 085 */ 086 public void setText(String text) { 087 this.text = text; 088 } 089 090 public void setId(String id) { 091 this.id = id; 092 } 093 094 @Override 095 public int doStartTag() throws PageException { 096 097 return EVAL_BODY_BUFFERED; 098 } 099 100 101 @Override 102 public int doEndTag() throws PageException { 103 104 processTag(); 105 106 return SKIP_BODY; 107 } 108 109 public int doAfterBody() throws PageException { 110 if (StringUtil.isEmpty(text) && bodyContent != null) { 111 text = bodyContent.getString(); 112 } 113 if(bodyContent!=null)bodyContent.clearBody(); 114 115 return SKIP_BODY; 116 } 117 118 protected void processTag() throws PageException { 119 120 try { 121 122 if (StringUtil.isEmpty(action, true) || action.equals("append")) { 123 124 required(getTagName(), "text", text); 125 if (isValid()) 126 actionAppend(); 127 } 128 else if (action.equals("reset")) { 129 130 resetIdMap(); 131 actionReset(); 132 } 133 else if (action.equals("write")) { 134 135 required(getTagName(), "text", text); 136 resetIdMap(); 137 if (isValid()) // call isValid() to register the id if set 138 actionWrite(); 139 } 140 else if (action.equals("read")) actionRead(); 141 else if (action.equals("flush")) actionFlush(); 142 else 143 throw new ApplicationException("invalid value [" + action + "] for attribute action", "values for attribute action are: [append], flush, read, reset, write"); 144 } catch (IOException e) { 145 throw Caster.toPageException(e); 146 } 147 } 148 149 /** 150 * 151 * @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 152 */ 153 protected boolean isValid() { 154 155 if (StringUtil.isEmpty(id)) 156 return true; 157 158 Map m = getIdMap(); 159 160 if (m.containsKey(id)) 161 return false; 162 163 m.put(id, Boolean.TRUE); 164 return true; 165 } 166 167 protected Map getIdMap() { 168 169 String reqAttr = REQUEST_ATTRIBUTE_PREFIX + getTagName(); 170 171 Map result = (Map)pageContext.getRequest().getAttribute(reqAttr); 172 173 if (result == null) { 174 175 result = new TreeMap(String.CASE_INSENSITIVE_ORDER); 176 pageContext.getRequest().setAttribute(reqAttr, result); 177 } 178 179 return result; 180 } 181 182 protected void resetIdMap() { 183 184 String reqAttr = REQUEST_ATTRIBUTE_PREFIX + getTagName(); 185 186 pageContext.getRequest().setAttribute(reqAttr, null); 187 } 188}