001 package railo.commons.io.ini; 002 003 import java.io.BufferedReader; 004 import java.io.IOException; 005 import java.io.InputStream; 006 import java.io.InputStreamReader; 007 import java.io.OutputStream; 008 import java.io.PrintWriter; 009 import java.util.Iterator; 010 import java.util.LinkedHashMap; 011 import java.util.Map; 012 013 import railo.commons.io.IOUtil; 014 import railo.commons.io.res.Resource; 015 import railo.runtime.type.Struct; 016 import railo.runtime.type.StructImpl; 017 018 /** 019 * read a ini file and allow to modifie and read the data 020 */ 021 public final class IniFile { 022 023 private Map sections; 024 private final Resource file; 025 026 private static Map newMap() {return new LinkedHashMap();} 027 028 /** 029 * Constructor for the IniFile object 030 * 031 * @param file ini FIle 032 * @throws IOException 033 */ 034 public IniFile(Resource file) throws IOException { 035 this.file=file; 036 sections = newMap(); 037 InputStream is=null; 038 if(!file.exists())file.createFile(false); 039 try { 040 load(is=file.getInputStream()); 041 } 042 finally { 043 IOUtil.closeEL(is); 044 } 045 } 046 047 public IniFile(InputStream is) throws IOException { 048 sections = newMap(); 049 load(is); 050 file=null; 051 } 052 053 /** 054 * Sets the KeyValue attribute of the IniFile object 055 * 056 * @param strSection the section to set 057 * @param key the key of the new value 058 * @param value the value to set 059 */ 060 public void setKeyValue(String strSection, String key, String value) { 061 Map section = getSectionEL(strSection); 062 if(section==null) { 063 section=newMap(); 064 sections.put(strSection.toLowerCase(),section); 065 } 066 section.put(key.toLowerCase(), value); 067 } 068 069 /** 070 * Gets the Sections attribute of the IniFile object 071 * 072 * @return The Sections value 073 */ 074 public Map getSections() { 075 return sections; 076 } 077 078 /** 079 * Gets the Section attribute of the IniFile object 080 * 081 * @param strSection section name to get 082 * @return The Section value 083 * @throws IOException 084 */ 085 public Map getSection(String strSection) throws IOException { 086 Object o=sections.get(strSection.toLowerCase()); 087 if(o==null) throw new IOException("section with name "+strSection+" does not exist"); 088 return (Map) o; 089 } 090 /** 091 * Gets the Section attribute of the IniFile object, return null if section not exist 092 * 093 * @param strSection section name to get 094 * @return The Section value 095 */ 096 public Map getSectionEL(String strSection) { 097 Object o=sections.get(strSection.toLowerCase()); 098 if(o==null) return null; 099 return (Map) o; 100 } 101 102 /** 103 * Gets the NullOrEmpty attribute of the IniFile object 104 * 105 * @param section section to check 106 * @param key key to check 107 * @return is empty or not 108 */ 109 public boolean isNullOrEmpty(String section, String key) { 110 String value = getKeyValueEL(section, key); 111 return (value == null || value.length() == 0); 112 } 113 114 /** 115 * Gets the KeyValue attribute of the IniFile object 116 * 117 * @param strSection section to get 118 * @param key key to get 119 * @return matching alue 120 * @throws IOException 121 */ 122 public String getKeyValue(String strSection, String key) throws IOException { 123 Object o= getSection(strSection).get(key.toLowerCase()); 124 if(o==null) throw new IOException("key "+key+" doesn't exist in section "+strSection); 125 return (String)o; 126 127 } 128 /** 129 * Gets the KeyValue attribute of the IniFile object, if not exists return null 130 * 131 * @param strSection section to get 132 * @param key key to get 133 * @return matching alue 134 */ 135 public String getKeyValueEL(String strSection, String key) { 136 Map map=getSectionEL(strSection); 137 if(map==null) return null; 138 Object o=map.get(key.toLowerCase()); 139 if(o==null) return null; 140 return (String) o; 141 142 } 143 144 145 /** 146 * loads the ini file 147 * @param in inputstream to read 148 * @throws IOException 149 */ 150 public void load(InputStream in) throws IOException { 151 152 BufferedReader input = IOUtil.toBufferedReader(new InputStreamReader(in)); 153 String read; 154 Map section = null; 155 String sectionName; 156 while ((read = input.readLine()) != null) { 157 if (read.startsWith(";") || read.startsWith("#")) { 158 continue; 159 } 160 else if (read.startsWith("[")) { 161 // new section 162 sectionName = read.substring(1, read.indexOf("]")).trim().toLowerCase(); 163 section = getSectionEL(sectionName); 164 if (section == null) { 165 section = newMap(); 166 sections.put(sectionName, section); 167 } 168 } 169 else if (read.indexOf("=") != -1 && section != null) { 170 // new key 171 String key = read.substring(0, read.indexOf("=")).trim().toLowerCase(); 172 String value = read.substring(read.indexOf("=") + 1).trim(); 173 if(section!=null)section.put(key, value); 174 } 175 } 176 177 } 178 179 /** 180 * save back content to ini file 181 * @throws IOException 182 */ 183 public void save() throws IOException { 184 if(!file.exists())file.createFile(true); 185 OutputStream out=IOUtil.toBufferedOutputStream(file.getOutputStream()); 186 Iterator it = sections.keySet().iterator(); 187 PrintWriter output = new PrintWriter(out); 188 try { 189 while(it.hasNext()) { 190 String strSection = (String) it.next(); 191 output.println("[" + strSection + "]"); 192 Map section = getSectionEL(strSection); 193 Iterator iit = section.keySet().iterator(); 194 while(iit.hasNext()) { 195 String key = (String) iit.next(); 196 output.println(key + "=" + section.get(key)); 197 } 198 } 199 } 200 finally { 201 IOUtil.flushEL(output); 202 IOUtil.closeEL(output); 203 IOUtil.flushEL(out); 204 IOUtil.closeEL(out); 205 } 206 } 207 208 /** 209 * removes a selection 210 * 211 * @param strSection section to remove 212 */ 213 public void removeSection(String strSection) { 214 sections.remove(strSection); 215 } 216 217 /** 218 * 219 * @param file 220 * @return return a struct with all section an dkey list as value 221 * @throws IOException 222 */ 223 public static Struct getProfileSections(Resource file) throws IOException { 224 IniFile ini=new IniFile(file); 225 Struct rtn=new StructImpl(Struct.TYPE_SYNC); 226 Map sections = ini.getSections(); 227 Iterator it = sections.keySet().iterator(); 228 while(it.hasNext()) { 229 String strSection=(String) it.next(); 230 Map section = ini.getSectionEL(strSection); 231 Iterator iit = section.keySet().iterator(); 232 StringBuilder sb=new StringBuilder(); 233 while(iit.hasNext()) { 234 if(sb.length()!=0)sb.append(','); 235 sb.append(iit.next()); 236 } 237 rtn.setEL(strSection,sb.toString()); 238 } 239 return rtn; 240 } 241 }