View Javadoc

1   package com.atlassian.sal.core.pluginsettings;
2   
3   import java.io.IOException;
4   import java.io.StringWriter;
5   import java.io.Writer;
6   
7   /**
8    * Escape utility methods which only escapes VERTICAL_TAB and NEW_LINE.
9    *
10   * The escape logic is custom made here instead of using StringEscapeUtils in apache common since
11   * we don't want to interfere with other special characters that we don't use in {@link AbstractStringPluginSettings}.
12   *
13   * For example, in that case if the data read from the backing store is "this is \\me", we're not sure whether
14   * it's escaped or non-escaped.
15   *
16   * @since 2.2.0
17   */
18  class EscapeUtils
19  {
20      // Not for instantiation.
21      private EscapeUtils()
22      {
23      }
24  
25      protected static final char VERTICAL_TAB = '\f';
26      protected static final char NEW_LINE = '\n';
27  
28      /**
29       * This only escapes VERTICAL_TAB and NEW_LINE.
30       */
31      protected static String escape(String str)
32      {
33          if (str == null)
34          {
35              return null;
36          }
37  
38          StringWriter writer = new StringWriter(str.length() * 2);
39          try
40          {
41              escape(writer, str);
42          }
43          catch (IOException e)
44          {
45              throw new RuntimeException("exception while writing to StringWriter (should be impossible in this context)", e);
46          }
47  
48          return writer.toString();
49      }
50  
51      private static void escape(Writer out, String str) throws IOException
52      {
53          int len = str.length();
54          for (int i = 0; i < len; i++)
55          {
56              char ch = str.charAt(i);
57  
58              if (ch == VERTICAL_TAB)
59              {
60                  out.write('\\');
61                  out.write('f');
62              }
63              else if (ch == NEW_LINE)
64              {
65                  out.write('\\');
66                  out.write('n');
67              }
68              else if (ch == '\\')
69              {
70                  out.write('\\');
71                  out.write('\\');
72              }
73              else
74              {
75                 out.write(ch);
76              }
77          }
78      }
79  
80      public static String unescape(String str)
81      {
82          if (str == null)
83          {
84              return null;
85          }
86          try
87          {
88              StringWriter writer = new StringWriter(str.length());
89              unescape(writer, str);
90              return writer.toString();
91          }
92          catch (IOException e)
93          {
94              throw new RuntimeException("exception while writing to StringWriter (should be impossible in this context)", e);
95          }
96       }
97  
98      private static void unescape(Writer out, String str) throws IOException
99      {
100         int len = str.length();
101         boolean hadSlash = false;
102 
103         for (int i = 0; i < len; i++) {
104             char ch = str.charAt(i);
105             if (hadSlash) {
106                 switch (ch) {
107                     case 'f':
108                         out.write('\f');
109                         break;
110                     case 'n':
111                         out.write('\n');
112                         break;
113                     default :
114                         out.write(ch);
115                         break;
116                 }
117                 // the slash is taken care of.
118                 hadSlash = false;
119                 continue;
120             } else if (ch == '\\') {
121                 hadSlash = true;
122                 continue;
123             }
124             out.write(ch);
125         }
126         // the the slash is the last character, then just give it out.
127         if (hadSlash) {
128             out.write('\\');
129         }
130     }
131 }