1:
37:
38: package ;
39:
40: import ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48:
49:
55: public class MimeTypeParameterList
56: {
57:
58: private final List<String> parameterNames;
59: private final Map<String,String> parameterValues;
60:
61:
64: public MimeTypeParameterList()
65: {
66: parameterNames = new ArrayList<String>();
67: parameterValues = new HashMap<String,String>();
68: }
69:
70:
74: public MimeTypeParameterList(String parameterList)
75: throws MimeTypeParseException
76: {
77: this();
78: parse(parameterList);
79: }
80:
81:
86: protected void parse(String parameterList)
87: throws MimeTypeParseException
88: {
89: if (parameterList == null)
90: {
91: return;
92: }
93:
94: char[] chars = parameterList.toCharArray();
95: int len = chars.length;
96: boolean inQuotedString = false;
97: CPStringBuilder buffer = new CPStringBuilder();
98: List<String> params = new ArrayList<String>();
99: for (int i = 0; i < len; i++)
100: {
101: char c = chars[i];
102: if (c == ';' && !inQuotedString)
103: {
104: String param = buffer.toString().trim();
105: if (param.length() > 0)
106: {
107: params.add(param);
108: }
109: buffer.setLength(0);
110: }
111: else
112: {
113: if (c == '"')
114: {
115: inQuotedString = !inQuotedString;
116: }
117: buffer.append(c);
118: }
119: }
120: String param = buffer.toString().trim();
121: if (param.length() > 0)
122: {
123: params.add(param);
124: }
125:
126:
127: for (Iterator<String> i = params.iterator(); i.hasNext();)
128: {
129: param = i.next();
130: int ei = param.indexOf('=');
131: if (ei == -1)
132: {
133: throw new MimeTypeParseException("Couldn't find the '=' that " +
134: "separates a parameter name " +
135: "from its value.");
136: }
137: String name = param.substring(0, ei).trim();
138: MimeType.checkValidity(name, "Parameter name is invalid");
139: String value = param.substring(ei + 1).trim();
140: len = value.length();
141: if (len > 1 && value.charAt(0) == '"' &&
142: value.charAt(len - 1) == '"')
143: {
144: value = unquote(value);
145: }
146: else
147: {
148: MimeType.checkValidity(name, "Parameter value is invalid");
149: }
150:
151: parameterNames.add(name);
152: parameterValues.put(name.toLowerCase(), value);
153: }
154: }
155:
156:
159: public synchronized int size()
160: {
161: return parameterNames.size();
162: }
163:
164:
167: public synchronized boolean isEmpty()
168: {
169: return parameterNames.isEmpty();
170: }
171:
172:
176: public synchronized String get(String name)
177: {
178: name = name.trim();
179: return parameterValues.get(name.toLowerCase());
180: }
181:
182:
187: public synchronized void set(String name, String value)
188: {
189: name = name.trim();
190: boolean exists = false;
191: for (String pname : parameterNames)
192: {
193: if (name.equalsIgnoreCase(pname))
194: {
195: exists = true;
196: }
197: }
198: if (!exists)
199: {
200: parameterNames.add(name);
201: }
202: parameterValues.put(name.toLowerCase(), value);
203: }
204:
205:
209: public synchronized void remove(String name)
210: {
211: name = name.trim();
212: for (Iterator<String> i = parameterNames.iterator();i.hasNext();)
213: {
214: String pname = i.next();
215: if (name.equalsIgnoreCase(pname))
216: {
217: i.remove();
218: }
219: }
220: parameterValues.remove(name.toLowerCase());
221: }
222:
223:
226:
227: @SuppressWarnings("rawtypes")
228: public synchronized Enumeration getNames()
229: {
230: return new IteratorEnumeration(parameterNames.iterator());
231: }
232:
233:
237: public synchronized String toString()
238: {
239: CPStringBuilder buffer = new CPStringBuilder();
240: for (String name : parameterNames)
241: {
242: String value = parameterValues.get(name.toLowerCase());
243:
244: buffer.append(';');
245: buffer.append(' ');
246: buffer.append(name);
247: buffer.append('=');
248: buffer.append(quote(value));
249: }
250: return buffer.toString();
251: }
252:
253: private static String quote(String value)
254: {
255: boolean needsQuoting = false;
256: int len = value.length();
257: for (int i = 0; i < len; i++)
258: {
259: if (!MimeType.isValidChar(value.charAt(i)))
260: {
261: needsQuoting = true;
262: break;
263: }
264: }
265:
266: if (needsQuoting)
267: {
268: CPStringBuilder buffer = new CPStringBuilder();
269: buffer.append('"');
270: for (int i = 0; i < len; i++)
271: {
272: char c = value.charAt(i);
273: if (c == '\\' || c == '"')
274: {
275: buffer.append('\\');
276: }
277: buffer.append(c);
278: }
279: buffer.append('"');
280: return buffer.toString();
281: }
282: return value;
283: }
284:
285: private static String unquote(String value)
286: {
287: int len = value.length();
288: CPStringBuilder buffer = new CPStringBuilder();
289: for (int i = 1; i < len - 1; i++)
290: {
291: char c = value.charAt(i);
292: if (c == '\\')
293: {
294: i++;
295: if (i < len - 1)
296: {
297: c = value.charAt(i);
298: if (c != '\\' && c != '"')
299: {
300: buffer.append('\\');
301: }
302: }
303: }
304: buffer.append(c);
305: }
306: return buffer.toString();
307: }
308:
309:
312: static class IteratorEnumeration
313: implements Enumeration<String>
314: {
315:
316: final Iterator<String> iterator;
317:
318: IteratorEnumeration(Iterator<String> iterator)
319: {
320: this.iterator = iterator;
321: }
322:
323: public boolean hasMoreElements()
324: {
325: return iterator.hasNext();
326: }
327:
328: public String nextElement()
329: {
330: return iterator.next();
331: }
332:
333: }
334:
335: }