001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.util; 020 021import java.util.Iterator; 022import java.util.Map; 023import java.util.Properties; 024import java.util.TreeMap; 025 026/** 027 * some useful methods for properties 028 * 029 * @version 1.0 030 */ 031public final class PropertiesUtils { 032 033 private static final String OTHER_WHITESPACE = "\t\r\n\014"; 034 private static final char[] HEXDIGIT = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 035 036 /** Private constructor to prevent instantiation. */ 037 private PropertiesUtils() 038 {} 039 040 /** 041 * <p> 042 * like Properties.store, but stores the properties in sorted order 043 * </p> 044 * 045 * @param properties the properties object 046 * @return String the properties, nicely formatted 047 */ 048 public static String toSortedString(final Properties properties ) 049 { 050 @SuppressWarnings( { "unchecked", "rawtypes" } ) final TreeMap< String, String > treemap = new TreeMap( properties ); 051 final StringBuilder string = new StringBuilder(); 052 final Iterator< Map.Entry< String, String > > iterator = treemap.entrySet().iterator(); 053 while( iterator.hasNext() ) 054 { 055 final Map.Entry< String, String > entry = iterator.next(); 056 final String key = entry.getKey(); 057 final String value = entry.getValue() == null ? "null" : entry.getValue(); 058 string.append(toLine(key, value)).append('\n'); 059 } 060 return string.toString(); 061 } 062 063 /** 064 * Generates a property file line from a supplied key and value. 065 * @param key the property's key 066 * @param value the property's value 067 * @return the converted string 068 */ 069 public static String toLine(final String key, final String value ) 070 { 071 return saveConvert( key, true ) + '=' + saveConvert( value, false ); 072 } 073 074 /** 075 * Encodes a property file string from a supplied key/value line. 076 * @param string the string to encode 077 * @param encodeWhiteSpace <code>true</code> if whitespace should be encoded also 078 * @return the converted string 079 */ 080 public static String saveConvert(final String string, final boolean encodeWhiteSpace ) 081 { 082 final int i = string.length(); 083 final StringBuilder stringbuffer = new StringBuilder( i * 2 ); 084 for( int i3 = 0; i3 < i; i3++ ) 085 { 086 final char c = string.charAt( i3 ); 087 switch( c ) 088 { 089 case ' ': 090 if( i3 == 0 || encodeWhiteSpace ) 091 { 092 stringbuffer.append( '\\' ); 093 } 094 stringbuffer.append( ' ' ); 095 break; 096 case '\\': 097 stringbuffer.append( '\\' ); 098 stringbuffer.append( '\\' ); 099 break; 100 case '\t': 101 stringbuffer.append( '\\' ); 102 stringbuffer.append( 't' ); 103 break; 104 case '\n': 105 stringbuffer.append( '\\' ); 106 stringbuffer.append( 'n' ); 107 break; 108 case '\r': 109 stringbuffer.append( '\\' ); 110 stringbuffer.append( 'r' ); 111 break; 112 case '\014': 113 stringbuffer.append( '\\' ); 114 stringbuffer.append( 'f' ); 115 break; 116 default: 117 if( c < 32 || c > 126 ) 118 { 119 stringbuffer.append( '\\' ); 120 stringbuffer.append( 'u' ); 121 stringbuffer.append( toHex( c >> 12 & 0xf ) ); 122 stringbuffer.append( toHex( c >> 8 & 0xf ) ); 123 stringbuffer.append( toHex( c >> 4 & 0xf ) ); 124 stringbuffer.append( toHex( c & 0xf ) ); 125 } 126 else 127 { 128 if( OTHER_WHITESPACE.indexOf( c ) != -1 ) 129 { 130 stringbuffer.append( '\\' ); 131 } 132 stringbuffer.append( c ); 133 } 134 } 135 } 136 return stringbuffer.toString(); 137 } 138 139 private static char toHex(final int i ) 140 { 141 return HEXDIGIT[i & 0xf]; 142 } 143}