1717
1818package pl .project13 .core .util ;
1919
20+ import nu .studer .java .util .OrderedProperties ;
21+ import pl .project13 .core .CannotReadFileException ;
22+
2023import javax .annotation .Nonnull ;
2124import javax .annotation .Nullable ;
22- import java .io .File ;
23- import java .io .FileInputStream ;
24- import java .io .InputStreamReader ;
25+ import java .io .*;
2526import java .nio .charset .Charset ;
27+ import java .nio .charset .StandardCharsets ;
28+ import java .util .Map ;
2629import java .util .Properties ;
2730
2831public class PropertyManager {
@@ -37,12 +40,121 @@ private static boolean isNotEmpty(@Nullable String value) {
3740 return null != value && !" " .equals (value .trim ().replaceAll (" " , "" ));
3841 }
3942
40- public static Properties readProperties (@ Nonnull File propertiesFile , @ Nonnull Charset sourceCharset ) throws Exception {
43+ public static Properties readProperties (@ Nonnull File propertiesFile ) throws CannotReadFileException {
44+ return PropertyManager .readProperties (propertiesFile , StandardCharsets .ISO_8859_1 );
45+ }
46+
47+ public static Properties readProperties (@ Nonnull File propertiesFile , @ Nonnull Charset charset ) throws CannotReadFileException {
4148 try (FileInputStream fis = new FileInputStream (propertiesFile );
42- InputStreamReader reader = new InputStreamReader (fis , sourceCharset )) {
43- final Properties retVal = new Properties ();
49+ InputStreamReader reader = new InputStreamReader (fis , charset )) {
50+ final OrderedProperties retVal = new OrderedProperties ();
4451 retVal .load (reader );
45- return retVal ;
52+ return retVal .toJdkProperties ();
53+ } catch (final Exception ex ) {
54+ throw new CannotReadFileException (ex );
55+ }
56+ }
57+
58+ public static void dumpProperties (OutputStream outputStream , OrderedProperties sortedLocalProperties ) throws IOException {
59+ try (Writer outputWriter = new OutputStreamWriter (outputStream , StandardCharsets .ISO_8859_1 )) {
60+ // use the OrderedProperties.store(Writer, ...)-method to avoid illegal reflective access warning
61+ // see: https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/523
62+ outputWriter .write ("#Generated by Git-Commit-Id-Plugin" );
63+ outputWriter .write (System .getProperty ("line.separator" ));
64+ for (Map .Entry <String , String > e : sortedLocalProperties .entrySet ()) {
65+ String key = saveConvert (e .getKey (), true , true );
66+ String val = saveConvert (e .getValue (), false , true );
67+ outputWriter .write (key + "=" + val );
68+ outputWriter .write (System .getProperty ("line.separator" ));
69+ }
4670 }
4771 }
72+
73+ /*
74+ * Converts unicodes to encoded \uxxxx and escapes
75+ * special characters with a preceding slash.
76+ * @see java.util.Properties#saveConvert
77+ */
78+ private static String saveConvert (String theString ,
79+ boolean escapeSpace ,
80+ boolean escapeUnicode ) {
81+ int len = theString .length ();
82+ int bufLen = len * 2 ;
83+ if (bufLen < 0 ) {
84+ bufLen = Integer .MAX_VALUE ;
85+ }
86+ StringBuffer outBuffer = new StringBuffer (bufLen );
87+
88+ for (int x = 0 ; x < len ; x ++) {
89+ char aChar = theString .charAt (x );
90+ // Handle common case first, selecting largest block that
91+ // avoids the specials below
92+ if ((aChar > 61 ) && (aChar < 127 )) {
93+ if (aChar == '\\' ) {
94+ outBuffer .append ('\\' );
95+ outBuffer .append ('\\' );
96+ continue ;
97+ }
98+ outBuffer .append (aChar );
99+ continue ;
100+ }
101+ switch (aChar ) {
102+ case ' ' :
103+ if (x == 0 || escapeSpace ) {
104+ outBuffer .append ('\\' );
105+ }
106+ outBuffer .append (' ' );
107+ break ;
108+ case '\t' :
109+ outBuffer .append ('\\' );
110+ outBuffer .append ('t' );
111+ break ;
112+ case '\n' :
113+ outBuffer .append ('\\' );
114+ outBuffer .append ('n' );
115+ break ;
116+ case '\r' :
117+ outBuffer .append ('\\' );
118+ outBuffer .append ('r' );
119+ break ;
120+ case '\f' :
121+ outBuffer .append ('\\' );
122+ outBuffer .append ('f' );
123+ break ;
124+ case '=' : // Fall through
125+ case ':' : // Fall through
126+ case '#' : // Fall through
127+ case '!' :
128+ outBuffer .append ('\\' );
129+ outBuffer .append (aChar );
130+ break ;
131+ default :
132+ if (((aChar < 0x0020 ) || (aChar > 0x007e )) & escapeUnicode ) {
133+ outBuffer .append ('\\' );
134+ outBuffer .append ('u' );
135+ outBuffer .append (toHex ((aChar >> 12 ) & 0xF ));
136+ outBuffer .append (toHex ((aChar >> 8 ) & 0xF ));
137+ outBuffer .append (toHex ((aChar >> 4 ) & 0xF ));
138+ outBuffer .append (toHex (aChar & 0xF ));
139+ } else {
140+ outBuffer .append (aChar );
141+ }
142+ }
143+ }
144+ return outBuffer .toString ();
145+ }
146+
147+ /**
148+ * Convert a nibble to a hex character
149+ * @param nibble the nibble to convert.
150+ */
151+ private static char toHex (int nibble ) {
152+ return hexDigit [(nibble & 0xF )];
153+ }
154+
155+ /** A table of hex digits */
156+ private static final char [] hexDigit = {
157+ '0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'A' ,'B' ,'C' ,'D' ,'E' ,'F'
158+ };
159+
48160}
0 commit comments