001    package railo.runtime.registry;
002    
003    import java.io.IOException;
004    import java.io.InputStream;
005    import java.io.StringWriter;
006    import java.util.ArrayList;
007    
008    import railo.commons.cli.Command;
009    import railo.commons.lang.StringUtil;
010    import railo.runtime.functions.string.ParseNumber;
011    import railo.runtime.op.Caster;
012    import railo.runtime.type.List;
013    
014    
015    /**
016     * 
017     */
018    public final class RegistryQuery {
019    
020      private static final char DQ='"'; 
021      private static final int lenDWORD=RegistryEntry.REGDWORD_TOKEN.length();
022      private static final int lenSTRING=RegistryEntry.REGSTR_TOKEN.length();
023      private static final String NO_NAME="<NO NAME>";
024      
025              /**
026               * execute a String query on command line
027             * @param query String to execute
028             * @return
029             * @throws IOException
030             * @throws InterruptedException
031             */
032            public static String executeQuery(String[] cmd) throws IOException, InterruptedException {
033                    return Command.execute(cmd);
034            }  
035      
036              /**
037               * gets a single value form the registry
038             * @param branch brach to get value from
039             * @param entry entry to get
040             * @param type type of the registry entry to get
041             * @return registry entry or null of not exist
042             * @throws RegistryException
043             * @throws IOException
044             * @throws InterruptedException
045             */
046            public static RegistryEntry getValue(String branch, String entry, short type) throws RegistryException, IOException, InterruptedException {
047                String[] cmd = new String[]{"reg","query",cleanBrunch(branch),"/v",entry};
048                    RegistryEntry[] rst = filter(executeQuery(cmd),branch,type);
049                if(rst.length==1) {
050                    return rst[0];
051                    //if(type==RegistryEntry.TYPE_ANY || type==r.getType()) return r;
052                }
053                return null;
054            }
055    
056            /**
057             * gets all entries of one branch
058             * @param branch
059             * @param type
060             * @return
061             * @throws RegistryException
062             * @throws IOException
063             * @throws InterruptedException
064             */
065            public static RegistryEntry[] getValues(String branch, short type) throws RegistryException, IOException, InterruptedException {
066                    String[] cmd = new String[]{"reg","query",branch};
067                    return filter(executeQuery(cmd),cleanBrunch(branch),type);
068            }
069    
070            /**
071             * writes a value to registry
072             * @param branch
073             * @param entry
074             * @param type
075             * @param value
076             * @throws RegistryException
077             * @throws IOException
078             * @throws InterruptedException
079             */
080            public static void setValue(String branch, String entry, short type, String value) throws RegistryException, IOException, InterruptedException {
081                
082                if(type==RegistryEntry.TYPE_KEY) {
083                    String fullKey=List.trim(branch,"\\")+"\\"+List.trim(entry,"\\");
084                    //String[] cmd = new String[]{"reg","add",cleanBrunch(fullKey),"/ve","/f"};
085                    String[] cmd = new String[]{"reg","add",cleanBrunch(fullKey),"/f"};
086                    executeQuery(cmd);
087                    }
088                else {
089                    if(type==RegistryEntry.TYPE_DWORD)value=Caster.toString(Caster.toIntValue(value,0));
090                    String[] cmd = new String[]{"reg","add",cleanBrunch(branch),"/v",entry,"/t",RegistryEntry.toStringType(type),"/d",value,"/f"};
091                    executeQuery(cmd);
092                }
093            }
094            
095            /**
096             * deletes a value or a key
097             * @param branch
098             * @param entry
099             * @throws IOException
100             * @throws InterruptedException
101             */
102            public static void deleteValue(String branch, String entry) throws IOException, InterruptedException {
103                if(entry==null) {
104                    String[] cmd = new String[]{"reg","delete",cleanBrunch(branch),"/f"};
105                    executeQuery(cmd);
106                    //executeQuery("reg delete \""+List.trim(branch,"\\")+"\"  /f");
107                }
108                else {
109                    String[] cmd = new String[]{"reg","delete",cleanBrunch(branch),"/v",entry,"/f"};
110                    executeQuery(cmd);
111                    //executeQuery("reg delete \""+List.trim(branch,"\\")+"\" /v "+entry+" /f");
112                }
113            }
114            
115            private static String cleanBrunch(String branch) {
116                    branch=branch.replace('/', '\\');
117                    branch=List.trim(branch,"\\");
118                    if(branch.length()==0) return "\\";
119                    return branch;
120            }
121            
122    
123            /**
124             * filter registry entries from the raw result
125             * @param string plain result to filter regisry entries
126             * @param branch
127             * @param type
128             * @return filtered entries
129             * @throws RegistryException
130             */
131            private static RegistryEntry[] filter(String string,String branch, short type) throws RegistryException {
132                    branch=List.trim(branch,"\\");
133                StringBuffer result=new StringBuffer();
134                    ArrayList array=new ArrayList();
135                    String[] arr=string.split("\n");
136                    
137                    for(int i=0;i<arr.length;i++) {
138                            String line=arr[i].trim();
139                            int indexDWORD=line.indexOf(RegistryEntry.REGDWORD_TOKEN);
140                            int indexSTRING=line.indexOf(RegistryEntry.REGSTR_TOKEN);
141                            
142                            if((indexDWORD!=-1) || (indexSTRING!=-1) ) {
143                                int index=(indexDWORD==-1)?indexSTRING:indexDWORD;
144                                int len=(indexDWORD==-1)?lenSTRING:lenDWORD;
145                                short _type=(indexDWORD==-1)?RegistryEntry.TYPE_STRING:RegistryEntry.TYPE_DWORD;
146                                
147                                    if(result.length()>0)result.append("\n");
148                                     
149                                    String _key=line.substring(0,index).trim();
150                                    String _value=StringUtil.substringEL(line,index+len+1,"").trim();
151                                    
152                                    if(_key.equals(NO_NAME)) _key="";
153                                        if(_type==RegistryEntry.TYPE_DWORD)_value=String.valueOf(ParseNumber.invoke(_value.substring(2),"hex",0));
154                                        RegistryEntry re = new RegistryEntry(_type,_key,_value);
155                                        if(type==RegistryEntry.TYPE_ANY || type==re.getType()) array.add(re);
156                                    //}
157                            }
158                            else if(line.indexOf(branch)==0 && (type==RegistryEntry.TYPE_ANY || type==RegistryEntry.TYPE_KEY)) {
159                                line=List.trim(line,"\\");
160                                if(branch.length()<line.length()) {
161                                    array.add(new RegistryEntry(RegistryEntry.TYPE_KEY,List.last(line,"\\",true),""));
162                                }
163                            }
164                    }
165                    return (RegistryEntry[])array.toArray(new RegistryEntry[array.size()]);
166            }
167    
168    
169    
170    
171    
172    
173    
174    
175    
176    
177    
178    static class StreamReader extends Thread {
179        private InputStream is;
180        private StringWriter sw;
181    
182        StreamReader(InputStream is) {
183          this.is = is;
184          sw = new StringWriter();
185        }
186    
187        /**
188         * @see java.lang.Thread#run()
189         */
190        public void run() {
191          try {
192            int c;
193            while ((c = is.read()) != -1)
194              sw.write(c);
195            }
196            catch (IOException e) {  }
197          }
198    
199        String getResult() {
200          return sw.toString();
201        }
202      }  
203    }
204    
205    
206