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