/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package jlibs.core.util.i18n; import java.io.BufferedWriter; import java.io.IOException; import java.util.NavigableSet; import java.util.TreeSet; /** * @author Santhosh Kumar T */ public final class PropertiesUtil{ public static void writeComments(BufferedWriter bw, String comments) throws IOException{ bw.write("#"); int len = comments.length(); int current = 0; int last = 0; char[] uu = new char[6]; uu[0] = '\\'; uu[1] = 'u'; while(current<len){ char c = comments.charAt(current); if(c>'\u00ff' || c=='\n' || c=='\r'){ if(last != current) bw.write(comments.substring(last, current)); if(c>'\u00ff'){ uu[2] = toHex((c >> 12) & 0xf); uu[3] = toHex((c >> 8) & 0xf); uu[4] = toHex((c >> 4) & 0xf); uu[5] = toHex( c & 0xf); bw.write(new String(uu)); }else{ bw.newLine(); if(c=='\r' && current!=len-1 && comments.charAt(current+1)=='\n'){ current++; } if(current==len-1 || (comments.charAt(current + 1)!='#' && comments.charAt(current+1)!='!')) bw.write("#"); } last = current + 1; } current++; } if(last!=current) bw.write(comments.substring(last, current)); bw.newLine(); } public static void writeProperty(BufferedWriter bw, String key, String value) throws IOException{ key = saveConvert(key, true, false); value = saveConvert(value, false, false); bw.write(key + "=" + value); bw.newLine(); } private static String saveConvert(String theString, boolean escapeSpace, boolean escapeUnicode){ int len = theString.length(); int bufLen = len * 2; if(bufLen<0) bufLen = Integer.MAX_VALUE; StringBuffer outBuffer = new StringBuffer(bufLen); for(int x=0; x<len; x++){ char aChar = theString.charAt(x); // Handle common case first, selecting largest block that // avoids the specials below if (aChar>61 && aChar<127){ if(aChar=='\\'){ outBuffer.append('\\'); outBuffer.append('\\'); continue; } outBuffer.append(aChar); continue; } switch(aChar){ case ' ': if (x == 0 || escapeSpace) outBuffer.append('\\'); outBuffer.append(' '); break; case '\t': outBuffer.append('\\'); outBuffer.append('t'); break; case '\n': outBuffer.append('\\'); outBuffer.append('n'); break; case '\r': outBuffer.append('\\'); outBuffer.append('r'); break; case '\f': outBuffer.append('\\'); outBuffer.append('f'); break; case '=': // Fall through case ':': // Fall through case '#': // Fall through case '!': outBuffer.append('\\'); outBuffer.append(aChar); break; default: if((aChar<0x0020 || aChar>0x007e) & escapeUnicode){ outBuffer.append('\\'); outBuffer.append('u'); outBuffer.append(toHex((aChar >> 12) & 0xF)); outBuffer.append(toHex((aChar >> 8) & 0xF)); outBuffer.append(toHex((aChar >> 4) & 0xF)); outBuffer.append(toHex( aChar & 0xF)); }else outBuffer.append(aChar); } } return outBuffer.toString(); } private static char toHex(int nibble){ return hexDigit[(nibble & 0xF)]; } /** A table of hex digits */ private static final char[] hexDigit ={ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; public static NavigableSet<Integer> findArgs(String pattern){ NavigableSet<Integer> args = new TreeSet<Integer>(); StringBuffer[] segments = new StringBuffer[4]; for(int i=0; i<segments.length; ++i) segments[i] = new StringBuffer(); int part = 0; boolean inQuote = false; int braceStack = 0; for(int i=0; i<pattern.length(); ++i){ char ch = pattern.charAt(i); if(part==0){ if(ch=='\''){ if(i+1<pattern.length() && pattern.charAt(i+1)=='\''){ segments[part].append(ch); // handle doubles ++i; }else inQuote = !inQuote; }else if(ch=='{'&&!inQuote) part = 1; else segments[part].append(ch); }else if(inQuote){ // just copy quotes in parts segments[part].append(ch); if(ch=='\'') inQuote = false; }else{ switch(ch){ case ',': if(part<3) part += 1; else segments[part].append(ch); break; case '{': ++braceStack; segments[part].append(ch); break; case '}': if(braceStack==0){ part = 0; args.add(Integer.parseInt(segments[1].toString())); segments[1].setLength(0); // throw away other segments segments[2].setLength(0); segments[3].setLength(0); }else{ --braceStack; segments[part].append(ch); } break; case '\'': inQuote = true; // fall through, so we keep quotes in other parts default: segments[part].append(ch); break; } } } if(braceStack==0 && part!=0) throw new IllegalArgumentException("Unmatched braces in the pattern."); return args; } }