]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/save/xml/XmlUtils.java
Version 18.2, December 2015
[GpsPrune.git] / tim / prune / save / xml / XmlUtils.java
1 package tim.prune.save.xml;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStreamWriter;
7 import java.nio.charset.Charset;
8
9 /**
10  * Collection of utility functions for handling XML
11  */
12 public abstract class XmlUtils
13 {
14         /** Start of Cdata sequence */
15         private static final String CDATA_START = "<![CDATA[";
16         /** End of Cdata sequence */
17         private static final String CDATA_END = "]]>";
18         /** Cached copy of system encoding string */
19         private static String _systemEncoding = null;
20
21         /**
22          * Fix the CDATA blocks in the given String to give valid xml
23          * @param inString String to modify
24          * @return fixed String
25          */
26         public static String fixCdata(String inString)
27         {
28                 if (inString == null || inString.isEmpty()) return "";
29                 if (!hasIllegalCharacter(inString)) {
30                         return inString;
31                 }
32                 String result = inString;
33                 // Remove cdata block at start if present
34                 if (result.startsWith(CDATA_START)) {
35                         result = result.substring(CDATA_START.length());
36                 }
37                 // Remove all instances of end block
38                 result = result.replaceAll(CDATA_END, "");
39                 // Now check whether cdata block is required
40                 if (!XmlUtils.hasIllegalCharacter(result)) {
41                         return result;
42                 }
43                 return CDATA_START + result + CDATA_END;
44         }
45
46         /**
47          * Checks the input string for the three illegal characters,
48          * but only looping through the string once instead of three times
49          * @param inValue string to check
50          * @return true if at least one of the illegal characters is found
51          */
52         public static boolean hasIllegalCharacter(String inValue)
53         {
54                 if (inValue == null) return false;
55                 final int numChars = inValue.length();
56                 for (int i=0; i<numChars; i++)
57                 {
58                         final char c = inValue.charAt(i);
59                         if (c == '<' || c == '>' || c == '&')
60                         {
61                                 return true;
62                         }
63                 }
64                 return false;
65         }
66
67         /**
68          * @return true if system uses UTF-8 by default
69          */
70         public static boolean isSystemUtf8()
71         {
72                 String systemEncoding = getSystemEncoding();
73                 return (systemEncoding != null && systemEncoding.toUpperCase().equals("UTF-8"));
74         }
75
76         /**
77          * @return name of the system's character encoding
78          */
79         public static String getSystemEncoding()
80         {
81                 if (_systemEncoding == null) {
82                         _systemEncoding = determineSystemEncoding();
83                 }
84                 return _systemEncoding;
85         }
86
87         /**
88          * Use a temporary file to obtain the name of the default system encoding
89          * @return name of default system encoding, or null if write failed
90          */
91         private static String determineSystemEncoding()
92         {
93                 File tempFile = null;
94                 String encoding = null;
95                 try
96                 {
97                         tempFile = File.createTempFile("gpsprune", null);
98                         OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile));
99                         encoding = getEncoding(writer);
100                         writer.close();
101                 }
102                 catch (IOException e) {} // value stays null
103                 // Delete temp file
104                 if (tempFile != null && tempFile.exists()) {
105                         if (!tempFile.delete()) {
106                                 System.err.println("Cannot delete temp file: " + tempFile.getAbsolutePath());
107                         }
108                 }
109                 // If writing failed (eg permissions) then just ask system for default
110                 if (encoding == null) encoding = Charset.defaultCharset().name();
111                 return encoding;
112         }
113
114
115         /**
116          * Get the default system encoding using a writer
117          * @param inWriter writer object
118          * @return string defining encoding
119          */
120         public static String getEncoding(OutputStreamWriter inWriter)
121         {
122                 String encoding = inWriter.getEncoding();
123                 try {
124                         encoding =  Charset.forName(encoding).name();
125                 }
126                 catch (Exception e) {} // ignore failure to find encoding
127                 return encoding;
128         }
129 }