KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > webservice > util > ISO9075


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.webservice.util;
18
19 import com.sun.org.apache.xerces.internal.util.XMLChar;
20
21 /**
22  * Support for the ISO 9075 encoding of XML element names.
23  *
24  * @author Andy Hind
25  */

26 public class ISO9075
27 {
28     /*
29      * Mask for hex encoding
30      */

31     private static final int MASK = (1 << 4) - 1;
32
33     /*
34      * Digits used string encoding
35      */

36     private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
37             'f' };
38
39     /**
40      * Private constructor
41      *
42      */

43     private ISO9075()
44     {
45         super();
46     }
47
48     /**
49      * Encode a string according to ISO 9075
50      *
51      * @param toEncode
52      * @return
53      */

54     public static String JavaDoc encode(String JavaDoc toEncode)
55     {
56         if ((toEncode == null) || (toEncode.length() == 0))
57         {
58             return toEncode;
59         }
60         else if (XMLChar.isValidName(toEncode) && (toEncode.indexOf("_x") == -1))
61         {
62             return toEncode;
63         }
64         else
65         {
66             StringBuilder JavaDoc builder = new StringBuilder JavaDoc(toEncode.length());
67             for (int i = 0; i < toEncode.length(); i++)
68             {
69                 char c = toEncode.charAt(i);
70                 // First requires special test
71
if (i == 0)
72                 {
73                     if (XMLChar.isNCNameStart(c))
74                     {
75                         // The first character may be the _ at the start of an
76
// encoding pattern
77
if (matchesEncodedPattern(toEncode, i))
78                         {
79                             // Encode the first _
80
encode('_', builder);
81                         }
82                         else
83                         {
84                             // Just append
85
builder.append(c);
86                         }
87                     }
88                     else
89                     {
90                         // Encode an invalid start character for an XML element
91
// name.
92
encode(c, builder);
93                     }
94                 }
95                 else if (!XMLChar.isNCName(c))
96                 {
97                     encode(c, builder);
98                 }
99                 else
100                 {
101                     if (matchesEncodedPattern(toEncode, i))
102                     {
103                         // '_' must be encoded
104
encode('_', builder);
105                     }
106                     else
107                     {
108                         builder.append(c);
109                     }
110                 }
111             }
112             return builder.toString();
113         }
114
115     }
116
117     private static boolean matchesEncodedPattern(String JavaDoc string, int position)
118     {
119         return (string.length() >= position + 6)
120                 && (string.charAt(position) == '_') && (string.charAt(position + 1) == 'x')
121                 && isHexChar(string.charAt(position + 2)) && isHexChar(string.charAt(position + 3))
122                 && isHexChar(string.charAt(position + 4)) && isHexChar(string.charAt(position + 5))
123                 && (string.charAt(position + 6) == '_');
124     }
125
126     private static boolean isHexChar(char c)
127     {
128         switch (c)
129         {
130         case '0':
131         case '1':
132         case '2':
133         case '3':
134         case '4':
135         case '5':
136         case '6':
137         case '7':
138         case '8':
139         case '9':
140         case 'a':
141         case 'b':
142         case 'c':
143         case 'd':
144         case 'e':
145         case 'f':
146         case 'A':
147         case 'B':
148         case 'C':
149         case 'D':
150         case 'E':
151         case 'F':
152             return true;
153         default:
154             return false;
155         }
156     }
157
158     public static String JavaDoc decode(String JavaDoc toDecode)
159     {
160         if ((toDecode == null) || (toDecode.length() < 7) || (toDecode.indexOf("_x") < 0))
161         {
162             return toDecode;
163         }
164         StringBuffer JavaDoc decoded = new StringBuffer JavaDoc();
165         for (int i = 0, l = toDecode.length(); i < l; i++)
166         {
167             if (matchesEncodedPattern(toDecode, i))
168             {
169                 decoded.append(((char) Integer.parseInt(toDecode.substring(i + 2, i + 6), 16)));
170                 i += 6;
171             }
172             else
173             {
174                 decoded.append(toDecode.charAt(i));
175             }
176         }
177         return decoded.toString();
178     }
179
180     private static void encode(char c, StringBuilder JavaDoc builder)
181     {
182         char[] buf = new char[] { '_', 'x', '0', '0', '0', '0', '_' };
183         int charPos = 6;
184         do
185         {
186             buf[--charPos] = DIGITS[c & MASK];
187             c >>>= 4;
188         }
189         while (c != 0);
190         builder.append(buf);
191     }
192 }
193
Popular Tags