1
2
3
4 package org.rcfaces.core.internal.contentAccessor;
5
6 import java.util.ArrayList;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10 import java.util.StringTokenizer;
11
12 import org.rcfaces.core.internal.lang.StringAppender;
13 import org.rcfaces.core.provider.AbstractProvider;
14
15
16
17
18
19
20 public abstract class AbstractCompositeContentAccessorHandler extends
21 AbstractProvider implements ICompositeContentAccessorHandler {
22 private static final String REVISION = "$Revision: 1.1 $";
23
24 private static final Set DEFAULT_CHARSETS = new HashSet(8);
25 static {
26 DEFAULT_CHARSETS.add("utf8");
27 DEFAULT_CHARSETS.add("utf-8");
28 DEFAULT_CHARSETS.add("utf 8");
29 DEFAULT_CHARSETS.add("utf_8");
30 }
31
32 public ICompositeURLDescriptor createCompositeURLDescriptor(
33 String mainCharSet) {
34 CompositeURLDescriptor compositeURLDescriptor = new CompositeURLDescriptor();
35
36 compositeURLDescriptor.initialize(mainCharSet);
37
38 return compositeURLDescriptor;
39 }
40
41 public ICompositeURLDescriptor parseCompositeURLDescriptor(
42 String compositeURL) {
43
44 CompositeURLDescriptor compositeURLDescriptor = new CompositeURLDescriptor();
45
46 compositeURLDescriptor.parse(compositeURL);
47
48 return compositeURLDescriptor;
49
50 }
51
52
53
54
55
56
57 protected static class CompositeURLDescriptor implements
58 ICompositeURLDescriptor {
59
60 private static final String MERGE_URL = COMPOSITE_OPERATION_ID
61 + IContentAccessor.FILTER_SEPARATOR;
62
63 private StringAppender sa;
64
65 private boolean first;
66
67 private String mainCharSet;
68
69 private IURLInformation[] urls;
70
71 protected CompositeURLDescriptor() {
72 }
73
74 public void initialize(String mainCharSet) {
75 sa = new StringAppender(MERGE_URL, 128);
76
77 if (mainCharSet != null
78 && DEFAULT_CHARSETS.contains(mainCharSet.toLowerCase()) == false) {
79
80 encodeParameter(sa, mainCharSet);
81 }
82
83 sa.append(':');
84
85 first = true;
86 }
87
88 public void addUrl(String src, String charSet) {
89
90 if (first) {
91 first = false;
92 } else {
93 sa.append('+');
94 }
95
96 if (charSet != null
97 && DEFAULT_CHARSETS.contains(charSet.toLowerCase()) == false) {
98 encodeParameter(sa, charSet);
99 }
100
101 sa.append(':');
102 encodeParameter(sa, src);
103 }
104
105 public String generateURL() {
106 return sa.toString();
107 }
108
109 public String getMainCharSet() {
110 return mainCharSet;
111 }
112
113 public IURLInformation[] listURLs() {
114 return urls;
115 }
116
117 public void parse(String compositedURL) {
118 StringTokenizer st = new StringTokenizer(compositedURL, ":", true);
119
120 String nextToken = st.nextToken();
121 if (nextToken.equals(":") == false) {
122 st.nextToken();
123
124 mainCharSet = decodeParameter(nextToken);
125 }
126
127 List urls = new ArrayList(st.countTokens() / 2);
128 for (; st.hasMoreTokens();) {
129 String urlCharSet = null;
130 nextToken = st.nextToken();
131 if (nextToken.equals(":") == false) {
132 st.nextToken();
133
134 urlCharSet = decodeParameter(nextToken);
135 }
136
137 final String _charSet = urlCharSet;
138 final String url = decodeParameter(nextToken);
139
140 urls.add(new IURLInformation() {
141
142 public String getCharSet() {
143 return _charSet;
144 }
145
146 public String getURL() {
147 return url;
148 }
149 });
150 }
151 }
152
153 private void encodeParameter(StringAppender sa, String value) {
154 char chs[] = value.toCharArray();
155
156 for (int i = 0; i < chs.length; i++) {
157 char c = chs[i];
158
159 if (Character.isLetterOrDigit(c) || c == '/' || c == '.') {
160 sa.append(c);
161 continue;
162 }
163
164 sa.append('%');
165 String hex = Integer.toHexString(c);
166 for (int l = 4 - hex.length(); l > 0; l--) {
167 sa.append('0');
168 }
169 sa.append(hex);
170 }
171 }
172
173 private String decodeParameter(String value) {
174 StringAppender sa = new StringAppender(value.length());
175
176 char chs[] = value.toCharArray();
177 for (int i = 0; i < chs.length;) {
178 char c = chs[i++];
179
180 if (c != '%') {
181 sa.append(c);
182 continue;
183 }
184
185 int hex = Integer.parseInt(value.substring(i, i + 4), 16);
186 sa.append((char) hex);
187 i += 4;
188 }
189
190 return sa.toString();
191 }
192
193 }
194
195 }