1616import java .io .OutputStream ;
1717import java .io .OutputStreamWriter ;
1818import java .io .Writer ;
19+ import java .nio .file .Path ;
20+ import java .nio .file .Paths ;
1921import java .util .Enumeration ;
2022import java .util .HashMap ;
2123import java .util .Map ;
2224import java .util .Properties ;
23- import java .util .StringTokenizer ;
2425import java .util .jar .JarEntry ;
2526import java .util .jar .JarFile ;
27+ import java .util .jar .Manifest ;
2628import java .util .prefs .Preferences ;
2729import java .util .regex .Matcher ;
2830import java .util .regex .Pattern ;
@@ -48,13 +50,13 @@ public static void save(final OutputStream stream) throws Exception
4850 {
4951 try
5052 (
51-
5253 final OutputStreamWriter out = new OutputStreamWriter (stream );
5354 )
5455 {
5556 out .append ("# Preference settings<br/>\n " );
5657 out .append ("# Format:<br/>\n " );
5758 out .append ("# the.package.name/key=value<br/>\n " );
59+ out .append ("<div style='color: red; font-weight: bold'># key=value in red are incorrect properties</div><br/>\n " );
5860 listSettings (getAllPropertyKeys (), out , Preferences .userRoot ());
5961 out .append ("# End.<br/>\n " );
6062 out .flush ();
@@ -76,9 +78,9 @@ private static void formatSetting(Map<String, String> allKeysWithPackages, final
7678 String keyFound = allKeysWithPackages .get (fullKey );
7779 boolean bNotFound = keyFound == null ? true : false ;
7880 if (bNotFound ) out .append ("<div style='color: red; font-weight: bold'>" );
79- out .append (fullKey )
81+ out .append (escapeHtml ( fullKey ) )
8082 .append ('=' )
81- .append (node .get (key , "" ))
83+ .append (escapeHtml ( node .get (key , "" ) ))
8284 .append ("<br/>\n " );
8385 if (bNotFound ) out .append ("</div>" );
8486 }
@@ -88,13 +90,14 @@ private static Map<String, String> getAllPropertyKeys() throws Exception
8890 Map <String , String > allKeysWithPackages = new HashMap <>();
8991
9092 String classpath = System .getProperty ("java.class.path" );
91- StringTokenizer tokenizer = new StringTokenizer ( classpath , System .getProperty ("path.separator" ));
93+ String [] jars = classpath . split ( System .getProperty ("path.separator" ));
9294
93- while (tokenizer .hasMoreTokens ()) {
94- String path = tokenizer .nextToken ();
95- File file = new File (path );
95+ if (jars .length == 1 ) jars = getAllJarFromManifest (jars [0 ]);
9696
97- if (path .endsWith (".jar" )) {
97+ for (String jarEntry : jars ) {
98+ File file = new File (jarEntry );
99+
100+ if (jarEntry .endsWith (".jar" )) {
98101 try (JarFile jarFile = new JarFile (file )) {
99102 Enumeration <JarEntry > entries = jarFile .entries ();
100103
@@ -111,7 +114,7 @@ private static Map<String, String> getAllPropertyKeys() throws Exception
111114 }
112115 }
113116 } catch (IOException e ) {
114- System .err .println ("Error opening JAR : " + path );
117+ System .err .println ("Error opening JAR : " + jarEntry );
115118 e .printStackTrace ();
116119 }
117120 }
@@ -120,44 +123,79 @@ private static Map<String, String> getAllPropertyKeys() throws Exception
120123 return allKeysWithPackages ;
121124 }
122125
123- private static void parsePropertiesWithPackage (
124- InputStream inputStream ,
125- String fileName ,
126- Map <String , String > allKeysWithPackages
127- ) {
128- Properties props = new Properties ();
129- String packageName = null ;
130-
131- try (BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream ))) {
132- String line ;
133- StringBuilder content = new StringBuilder ();
134-
135- while ((line = reader .readLine ()) != null ) {
136- line = line .trim ();
137- if (line .startsWith ("#" ) && line .contains ("Package" )) {
138- // Find package name
139- Pattern pattern = Pattern .compile ("#\\ s*Package\\ s+([^\\ s]+)" );
140- Matcher matcher = pattern .matcher (line );
141- if (matcher .find ()) {
142- packageName = matcher .group (1 );
143- }
144- } else if (!line .startsWith ("#" )) {
145- content .append (line ).append ("\n " );
126+ private static String [] getAllJarFromManifest (String jarPath ) {
127+ String [] jars = new String [0 ];
128+ File jarFile = new File (jarPath );
129+
130+ try (JarFile jar = new JarFile (jarFile )) {
131+ Manifest manifest = jar .getManifest ();
132+
133+ if (manifest != null ) {
134+ String classPath = manifest .getMainAttributes ().getValue ("Class-Path" );
135+
136+ if (classPath != null && !classPath .isEmpty ()) {
137+ jars = classPath .split (" " );
138+
139+ for (int iJar = 0 ; iJar < jars .length ; iJar ++) {
140+ Path fullPath = Paths .get (jarFile .getParent ()).resolve (jars [iJar ]);
141+ jars [iJar ] = fullPath .toString ();
146142 }
143+ } else {
144+ System .err .println ("No Class-Path found in MANIFEST.MF." );
147145 }
146+ } else {
147+ System .err .println ("MANIFEST.MF not found in the JAR." );
148+ }
149+ } catch (IOException e ) {
150+ System .err .println ("Error when reading the jar : " + jarPath );
151+ e .printStackTrace ();
152+ }
153+
154+ return jars ;
155+ }
156+
157+ private static void parsePropertiesWithPackage (InputStream inputStream , String fileName , Map <String , String > allKeysWithPackages ) {
158+ Properties props = new Properties ();
159+ String packageName = null ;
148160
149- if ( content . length () > 0 ) {
150- props . load ( new ByteArrayInputStream ( content . toString (). getBytes ())) ;
151- }
161+ try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( inputStream )) ) {
162+ String line ;
163+ StringBuilder content = new StringBuilder ();
152164
153- // properties found
154- for (String key : props .stringPropertyNames ()) {
155- String prefixedKey = (packageName != null ) ? packageName + "/" + key : key ;
156- allKeysWithPackages .put (prefixedKey , props .getProperty (key ));
165+ while ((line = reader .readLine ()) != null ) {
166+ line = line .trim ();
167+ if (line .startsWith ("#" ) && line .contains ("Package" )) {
168+ // Find package name
169+ Pattern pattern = Pattern .compile ("#\\ s*Package\\ s+([^\\ s]+)" );
170+ Matcher matcher = pattern .matcher (line );
171+ if (matcher .find ()) {
172+ packageName = matcher .group (1 );
173+ }
174+ } else if (!line .startsWith ("#" )) {
175+ content .append (line ).append ("\n " );
157176 }
158- } catch (IOException e ) {
159- System .err .println ("Error when reading file " + fileName );
160- e .printStackTrace ();
161177 }
178+
179+ if (content .length () > 0 ) {
180+ props .load (new ByteArrayInputStream (content .toString ().getBytes ()));
181+ }
182+
183+ // properties found
184+ for (String key : props .stringPropertyNames ()) {
185+ String prefixedKey = (packageName != null ) ? packageName + "/" + key : key ;
186+ allKeysWithPackages .put (prefixedKey , props .getProperty (key ));
187+ }
188+ } catch (IOException e ) {
189+ System .err .println ("Error when reading file " + fileName );
190+ e .printStackTrace ();
162191 }
192+ }
193+
194+ private static String escapeHtml (String input ) {
195+ return input .replace ("&" , "&" )
196+ .replace ("<" , "<" )
197+ .replace (">" , ">" )
198+ .replace ("\" " , """ )
199+ .replace ("'" , "'" );
200+ }
163201}
0 commit comments