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 lucee.runtime.exp.ApplicationException; 022import lucee.runtime.exp.PageException; 023import lucee.runtime.exp.SecurityException; 024import lucee.runtime.ext.tag.TagImpl; 025import lucee.runtime.op.Caster; 026import lucee.runtime.registry.RegistryEntry; 027import lucee.runtime.registry.RegistryQuery; 028import lucee.runtime.security.SecurityManager; 029import lucee.runtime.type.KeyImpl; 030import lucee.runtime.type.QueryImpl; 031import lucee.runtime.type.util.KeyConstants; 032 033/** 034* Reads, writes, and deletes keys and values in the system registry. The cfregistry tag is supported 035* on all platforms, including Linux, Solaris, and HP-UX. 036* 037* 038* 039**/ 040public final class Registry extends TagImpl { 041 042 private static final short ACTION_GET_ALL=0; 043 private static final short ACTION_GET=1; 044 private static final short ACTION_SET=2; 045 private static final short ACTION_DELETE=3; 046 047 048 049 /** Value data to set. If you omit this attribute, cfregistry creates default value, as follows: 050 ** 051 ** string: creates an empty string: "" 052 ** dWord: creates a value of 0 (zero) */ 053 private String value; 054 055 /** action to the registry */ 056 private short action=-1; 057 058 /** Sorts query column data (case-insensitive). Sorts on Entry, Type, and Value columns as text. Specify a combination of columns from query output, in a comma-delimited list. For example: 059 ** sort = "value desc, entry asc" 060 ** 061 ** asc: ascending (a to z) sort order 062 ** desc: descending (z to a) sort order */ 063 private String sort; 064 065 /** string: return string values 066 ** dWord: return DWord values 067 ** key: return keys 068 ** any: return keys and values */ 069 private short type=RegistryEntry.TYPE_ANY; 070 071 /** Name of a registry branch. */ 072 private String branch; 073 074 /** Registry value to access. */ 075 private String entry; 076 077 /** Variable into which to put value. */ 078 private String variable; 079 080 /** Name of record set to contain returned keys and values. */ 081 private String name; 082 083 084 @Override 085 public void release() { 086 super.release(); 087 value=null; 088 action=-1; 089 sort=null; 090 type=RegistryEntry.TYPE_ANY; 091 branch=null; 092 entry=null; 093 variable=null; 094 name=null; 095 } 096 097 /** set the value value 098 * Value data to set. If you omit this attribute, cfregistry creates default value, as follows: 099 * 100 * string: creates an empty string: "" 101 * dWord: creates a value of 0 (zero) 102 * @param value value to set 103 **/ 104 public void setValue(String value) { 105 this.value=value; 106 } 107 108 /** set the value action 109 * action to the registry 110 * @param action value to set 111 * @throws ApplicationException 112 **/ 113 public void setAction(String action) throws ApplicationException { 114 action=action.toLowerCase().trim(); 115 if(action.equals("getall")) this.action=ACTION_GET_ALL; 116 else if(action.equals("get")) this.action=ACTION_GET; 117 else if(action.equals("set")) this.action=ACTION_SET; 118 else if(action.equals("delete")) this.action=ACTION_DELETE; 119 else throw new ApplicationException("attribute action of the tag registry has an invalid value ["+action+"], valid values are [getAll, get, set, delete]"); 120 } 121 122 /** set the value sort 123 * Sorts query column data (case-insensitive). Sorts on Entry, Type, and Value columns as text. Specify a combination of columns from query output, in a comma-delimited list. For example: 124 * sort = "value desc, entry asc" 125 * 126 * asc: ascending (a to z) sort order 127 * desc: descending (z to a) sort order 128 * @param sort value to set 129 **/ 130 public void setSort(String sort) { 131 this.sort=sort; 132 } 133 134 /** set the value type 135 * string: return string values 136 * dWord: return DWord values 137 * key: return keys 138 * any: return keys and values 139 * @param type value to set 140 * @throws ApplicationException 141 **/ 142 public void setType(String type) throws ApplicationException { 143 type=type.toLowerCase().trim(); 144 if(type.equals("string")) this.type=RegistryEntry.TYPE_STRING; 145 else if(type.equals("dword")) this.type=RegistryEntry.TYPE_DWORD; 146 else if(type.equals("key")) this.type=RegistryEntry.TYPE_KEY; 147 else if(type.equals("any")) this.type=RegistryEntry.TYPE_ANY; 148 else throw new ApplicationException("attribute type of the tag registry has an invalid value ["+type+"], valid values are [string, dword]"); 149 } 150 151 /** set the value branch 152 * Name of a registry branch. 153 * @param branch value to set 154 **/ 155 public void setBranch(String branch) { 156 this.branch=branch; 157 } 158 159 /** set the value entry 160 * Registry value to access. 161 * @param entry value to set 162 **/ 163 public void setEntry(String entry) { 164 this.entry=entry; 165 } 166 167 /** set the value variable 168 * Variable into which to put value. 169 * @param variable value to set 170 **/ 171 public void setVariable(String variable) { 172 this.variable=variable; 173 } 174 175 /** set the value name 176 * Name of record set to contain returned keys and values. 177 * @param name value to set 178 **/ 179 public void setName(String name) { 180 this.name=name; 181 } 182 183 184 @Override 185 public int doStartTag() throws PageException { 186 if(pageContext.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_TAG_REGISTRY)==SecurityManager.VALUE_NO) 187 throw new SecurityException("can't access tag [registry]","access is prohibited by security manager"); 188 189 190 if(action==ACTION_GET) doGet(); 191 else if(action==ACTION_GET_ALL) doGetAll(); 192 else if(action==ACTION_SET) doSet(); 193 else if(action==ACTION_DELETE) doDelete(); 194 195 196 197 return SKIP_BODY; 198 } 199 200 /** 201 * @throws PageException 202 * 203 */ 204 private void doDelete() throws PageException { 205 try { 206 RegistryQuery.deleteValue(branch,entry); 207 } 208 catch (Exception e) { 209 throw Caster.toPageException(e); 210 } 211 } 212 213 /** 214 * @throws PageException 215 * 216 */ 217 private void doSet() throws PageException { 218 if(entry==null)throw new ApplicationException("attribute entry is required for tag registry, when action is [set]"); 219 if(type==RegistryEntry.TYPE_ANY)type=RegistryEntry.TYPE_STRING; 220 if(value==null) { 221 if(type==RegistryEntry.TYPE_DWORD)value="0"; 222 else value=""; 223 } 224 225 try { 226 RegistryQuery.setValue(branch,entry,type,value); 227 } 228 catch (Exception e) { 229 throw Caster.toPageException(e); 230 } 231 232 } 233 234 /** 235 * @throws PageException 236 * 237 */ 238 private void doGetAll() throws PageException { 239 if(name==null)throw new ApplicationException("attribute name is required for tag registry, when action is [getAll]"); 240 241 242 try { 243 RegistryEntry[] entries = RegistryQuery.getValues(branch,type); 244 if(entries!=null) { 245 lucee.runtime.type.Query qry=new QueryImpl( 246 new String[]{"entry","type","value"}, 247 new String[]{"VARCHAR","VARCHAR","OTHER"}, 248 entries.length,"query"); 249 for(int i=0;i<entries.length;i++) { 250 RegistryEntry e = entries[i]; 251 int row=i+1; 252 qry.setAt(KeyConstants._entry,row,e.getKey()); 253 qry.setAt(KeyConstants._type,row,RegistryEntry.toCFStringType(e.getType())); 254 qry.setAt(KeyConstants._value,row,e.getValue()); 255 } 256 257 258 // sort 259 if(sort!=null) { 260 String[] arr=sort.toLowerCase().split(","); 261 for(int i=arr.length-1;i>=0;i--) { 262 String[] col=arr[i].trim().split("\\s+"); 263 if(col.length==1)qry.sort(KeyImpl.init(col[0].trim())); 264 else if(col.length==2) { 265 String order=col[1].toLowerCase().trim(); 266 if(order.equals("asc")) 267 qry.sort(KeyImpl.init(col[0]),lucee.runtime.type.Query.ORDER_ASC); 268 else if(order.equals("desc")) 269 qry.sort(KeyImpl.init(col[0]),lucee.runtime.type.Query.ORDER_DESC); 270 else 271 throw new ApplicationException("invalid order type ["+col[1]+"]"); 272 } 273 } 274 } 275 276 277 278 279 280 281 282 pageContext.setVariable(name,qry); 283 } 284 } 285 catch (Exception e) { 286 throw Caster.toPageException(e); 287 } 288 289 } 290 291 /** 292 * @throws PageException 293 * 294 */ 295 private void doGet() throws PageException { 296 // "HKEY_LOCAL_MACHINE\\SOFTWARE\\Google\\NavClient","installtime" 297 if(entry==null)throw new ApplicationException("attribute entry is required for tag registry, when action is [get]"); 298 if(variable==null)throw new ApplicationException("attribute variable is required for tag registry, when action is [get]"); 299 //if(type==-1)throw new ApplicationException("attribute type is required for tag registry, when action is [get]"); 300 301 302 try { 303 RegistryEntry re = RegistryQuery.getValue(branch,entry,type); 304 if(re!=null)pageContext.setVariable(variable,re.getValue()); 305 } 306 catch (Exception e) { 307 throw Caster.toPageException(e); 308 } 309 310 } 311 312 @Override 313 public int doEndTag() { 314 return EVAL_PAGE; 315 } 316 317}