package eu.irreality.age.util; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.util.Properties; import java.util.Scanner; /** * In Java 1.6, there is a Properties.load(Reader) method that can be used to read .properties files * in encodings different from ISO-8859-1. * * This class contains a cheap, ugly workaround to be able to do the same in Java 1.5. * @author carlos * */ public class UTF8PropertiesLoader { public static String convertStreamToString(InputStream is) { return new Scanner(is).useDelimiter("\\A").next(); } /** * Converts the given string to ISO-8859-1, in such a way that if a character of the source string is not representable in that charset, it is * escaped. * @param src * @return */ public static String toIsoWithEscapes( String src ) { //final String src = "Hallo ���"; // this has to be read with the right encoding final CharsetEncoder asciiEncoder = Charset.forName("US-ASCII").newEncoder(); //US-ASCII, because if US-ASCII can encode it, then the char is the same in UTF as in ISO final StringBuilder result = new StringBuilder(); char[] arr = src.toCharArray(); for ( int i = 0 ; i < arr.length ; i++ ) { char character = arr[i]; if (asciiEncoder.canEncode(character)) { result.append(character); //character needs no modification } else //just use an unicode escape { result.append("\\u"); result.append(Integer.toHexString(0x10000 | character).substring(1).toUpperCase()); } /* //directly from the internets if ((arr[i] > '')) //characters that aren't the same in ISO and in UTF-8 (i.e. non-US-ASCII chars). That char is char 127. \u007f { // wr\uddddte ? result.append('\\'); result.append('u'); String hex = Integer.toHexString(arr[i]); StringBuffer hex4 = new StringBuffer(hex); hex4.reverse(); int length = 4 - hex4.length(); for (int j = 0; j < length; j++) { hex4.append('0'); } for (int j = 0; j < 4; j++) { result.append(hex4.charAt(3 - j)); } } else result.append(arr[i]); */ } return result.toString(); } /** * Loads properties from a custom encoding properties file, in an 1.5-compatible way. * @param p The Properties object to store properties into. * @param is The InputStream to get the properties from. * @param encoding The encoding associated with the data to get from the InputStream. * @throws IOException */ public static void loadProperties ( Properties p , InputStream is , String encoding ) throws IOException { final char[] buffer = new char[0x10000]; StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(is, encoding); int read; do { read = in.read(buffer, 0, buffer.length); if (read>0) { out.append(buffer, 0, read); } } while (read>=0); String propertiesAsString = out.toString(); //ByteArrayInputStream bais = new ByteArrayInputStream(propertiesAsString.getBytes("ISO-8859-1")); ByteArrayInputStream bais = new ByteArrayInputStream(toIsoWithEscapes(propertiesAsString).getBytes()); p.load(bais); bais.close(); in.close(); } }