| 1 21 22 package com.izforge.izpack.util; 23 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.InputStreamReader ; 27 import java.io.OutputStream ; 28 import java.io.OutputStreamWriter ; 29 import java.io.Reader ; 30 import java.io.Serializable ; 31 import java.io.StringReader ; 32 import java.io.StringWriter ; 33 import java.io.UnsupportedEncodingException ; 34 import java.io.Writer ; 35 import java.util.HashMap ; 36 import java.util.Map ; 37 import java.util.Properties ; 38 39 51 public class VariableSubstitutor implements Serializable  52 { 53 54 57 private static final long serialVersionUID = 3907213762447685687L; 58 59 60 protected transient Properties variables; 61 62 63 protected boolean bracesRequired = false; 64 65 66 protected final static int TYPE_PLAIN = 0; 67 68 69 protected final static int TYPE_JAVA_PROPERTIES = 1; 70 71 72 protected final static int TYPE_XML = 2; 73 74 75 protected final static int TYPE_SHELL = 3; 76 77 78 protected final static int TYPE_AT = 4; 79 80 81 public final static String PLAIN = "plain"; 82 83 84 protected final static Map typeNameToConstantMap; 85 86 static 88 { 89 typeNameToConstantMap = new HashMap (); 90 typeNameToConstantMap.put("plain", new Integer (TYPE_PLAIN)); 91 typeNameToConstantMap.put("javaprop", new Integer (TYPE_JAVA_PROPERTIES)); 92 typeNameToConstantMap.put("xml", new Integer (TYPE_XML)); 93 typeNameToConstantMap.put("shell", new Integer (TYPE_SHELL)); 94 typeNameToConstantMap.put("at", new Integer (TYPE_AT)); 95 } 96 97 103 public VariableSubstitutor(Properties variables) 104 { 105 this.variables = variables; 106 } 107 108 111 public boolean areBracesRequired() 112 { 113 return bracesRequired; 114 } 115 116 119 public void setBracesRequired(boolean braces) 120 { 121 bracesRequired = braces; 122 } 123 124 133 public String substitute(String str, String type) throws IllegalArgumentException  134 { 135 if (str == null) return null; 136 137 StringReader reader = new StringReader (str); 139 StringWriter writer = new StringWriter (); 140 141 try 143 { 144 substitute(reader, writer, type); 145 } 146 catch (IOException e) 147 { 148 throw new Error ("Unexpected I/O exception when reading/writing memory " 149 + "buffer; nested exception is: " + e); 150 } 151 152 return writer.getBuffer().toString(); 154 } 155 156 170 public int substitute(InputStream in, OutputStream out, String type, String encoding) 171 throws IllegalArgumentException , UnsupportedEncodingException , IOException  172 { 173 if (encoding == null) 175 { 176 int t = getTypeConstant(type); 177 switch (t) 178 { 179 case TYPE_JAVA_PROPERTIES: 180 encoding = "ISO-8859-1"; 181 break; 182 case TYPE_XML: 183 encoding = "UTF-8"; 184 break; 185 } 186 } 187 188 InputStreamReader reader = (encoding != null ? new InputStreamReader (in, encoding) 190 : new InputStreamReader (in)); 191 OutputStreamWriter writer = (encoding != null ? new OutputStreamWriter (out, encoding) 192 : new OutputStreamWriter (out)); 193 194 int subs = substitute(reader, writer, type); 196 197 writer.flush(); 199 200 return subs; 201 } 202 203 215 public String substitute( InputStream in, String type 216 ) 217 throws IllegalArgumentException , UnsupportedEncodingException , 218 IOException  219 { 220 String encoding = PLAIN; 222 { 223 int t = getTypeConstant( type ); 224 225 switch( t ) 226 { 227 case TYPE_JAVA_PROPERTIES: 228 encoding = "ISO-8859-1"; 229 230 break; 231 232 case TYPE_XML: 233 encoding = "UTF-8"; 234 235 break; 236 } 237 } 238 239 InputStreamReader reader = ( ( encoding != null ) 241 ? new InputStreamReader ( in, encoding ) 242 : new InputStreamReader ( in ) ); 243 StringWriter writer = new StringWriter ( ) ; 244 245 substitute( reader, writer, type ); 247 248 writer.flush( ); 250 251 return writer.getBuffer().toString(); 252 } 253 254 255 267 public int substitute(Reader reader, Writer writer, String type) 268 throws IllegalArgumentException , IOException  269 { 270 int t = getTypeConstant(type); 272 273 char variable_start = '$'; 275 if (t == TYPE_SHELL) 276 variable_start = '%'; 277 else if (t == TYPE_AT) variable_start = '@'; 278 279 int subs = 0; 280 281 int c = reader.read(); 283 if( c == 0xEF ) 285 { 286 for (int i = 0; i < 2; i++) 287 { 288 c = reader.read(); 289 } 290 } 291 if( c > 0xFF ) 293 c = reader.read(); 294 while (true) 295 { 296 while (c != -1 && c != variable_start) 298 { 299 writer.write(c); 300 c = reader.read(); 301 } 302 if (c == -1) return subs; 303 304 boolean braces = false; 306 c = reader.read(); 307 if (c == '{') 308 { 309 braces = true; 310 c = reader.read(); 311 } 312 else if (bracesRequired) 313 { 314 writer.write(variable_start); 315 continue; 316 } 317 else if (c == -1) 318 { 319 writer.write(variable_start); 320 return subs; 321 } 322 323 StringBuffer nameBuffer = new StringBuffer (); 325 while (c != -1 && (braces && c != '}') || (c >= 'a' && c <= 'z') 326 || (c >= 'A' && c <= 'Z') || (braces && (c == '[') || (c == ']')) 327 || (((c >= '0' && c <= '9') || c == '_') && nameBuffer.length() > 0)) 328 { 329 nameBuffer.append((char) c); 330 c = reader.read(); 331 } 332 String name = nameBuffer.toString(); 333 334 String varvalue = null; 336 337 if ((!braces || c == '}') && name.length() > 0) 338 { 339 if (braces && name.startsWith("ENV[") 341 && (name.lastIndexOf(']') == name.length() - 1)) 342 { 343 varvalue = IoHelper.getenv(name.substring(4, name.length() - 1)); 344 } 345 else 346 varvalue = variables.getProperty(name); 347 348 subs++; 349 } 350 351 if (varvalue != null) 353 { 354 writer.write(escapeSpecialChars(varvalue, t)); 355 if (braces) c = reader.read(); 356 } 357 else 359 { 360 writer.write(variable_start); 361 if (braces) writer.write('{'); 362 writer.write(name); 363 } 364 } 365 } 366 367 373 protected int getTypeConstant(String type) 374 { 375 if (type == null) return TYPE_PLAIN; 376 Integer integer = (Integer ) typeNameToConstantMap.get(type); 377 if (integer == null) 378 throw new IllegalArgumentException ("Unknown file type " + type); 379 else 380 return integer.intValue(); 381 } 382 383 390 protected String escapeSpecialChars(String str, int type) 391 { 392 StringBuffer buffer; 393 int len; 394 int i; 395 switch (type) 396 { 397 case TYPE_PLAIN: 398 case TYPE_SHELL: 399 case TYPE_AT: 400 return str; 401 case TYPE_JAVA_PROPERTIES: 402 buffer = new StringBuffer (str); 403 len = str.length(); 404 for (i = 0; i < len; i++) 405 { 406 char c = buffer.charAt(i); 408 if (c == '\t' || c == '\n' || c == '\r') 409 { 410 char tag; 411 if (c == '\t') 412 tag = 't'; 413 else if (c == '\n') 414 tag = 'n'; 415 else 416 tag = 'r'; 417 buffer.replace(i, i + 1, "\\" + tag); 418 len++; 419 i++; 420 } 421 422 if (c == '\\' || c == '"' || c == '\'' || c == ' ') 424 { 425 buffer.insert(i, '\\'); 426 len++; 427 i++; 428 } 429 } 430 return buffer.toString(); 431 case TYPE_XML: 432 buffer = new StringBuffer (str); 433 len = str.length(); 434 for (i = 0; i < len; i++) 435 { 436 String r = null; 437 char c = buffer.charAt(i); 438 switch (c) 439 { 440 case '<': 441 r = "<"; 442 break; 443 case '>': 444 r = ">"; 445 break; 446 case '&': 447 r = "&"; 448 break; 449 case '\'': 450 r = "'"; 451 break; 452 case '"': 453 r = """; 454 break; 455 } 456 if (r != null) 457 { 458 buffer.replace(i, i + 1, r); 459 len = buffer.length(); 460 i += r.length() - 1; 461 } 462 } 463 return buffer.toString(); 464 default: 465 throw new Error ("Unknown file type constant " + type); 466 } 467 } 468 } 469 | Popular Tags |