001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package javax.activation; 021 022 import java.util.Collections; 023 import java.util.Enumeration; 024 import java.util.HashMap; 025 import java.util.Iterator; 026 import java.util.Map; 027 028 029 /** 030 * @version $Rev: 467553 $ $Date: 2006-10-25 06:01:51 +0200 (Mi, 25. Okt 2006) $ 031 */ 032 public class MimeTypeParameterList { 033 034 private final Map params = new HashMap(); 035 036 public MimeTypeParameterList() { 037 } 038 039 public MimeTypeParameterList(String parameterList) throws MimeTypeParseException { 040 parse(parameterList); 041 } 042 043 protected void parse(String parameterList) throws MimeTypeParseException { 044 if (parameterList == null) { 045 throw new MimeTypeParseException("parameterList is null"); 046 } 047 048 RFC2045Parser parser = new RFC2045Parser(parameterList); 049 while (parser.hasMoreParams()) { 050 String attribute = parser.expectAttribute(); 051 parser.expectEquals(); 052 String value = parser.expectValue(); 053 params.put(attribute.toLowerCase(), value); 054 } 055 } 056 057 public int size() { 058 return params.size(); 059 } 060 061 public boolean isEmpty() { 062 return params.isEmpty(); 063 } 064 065 public String get(String name) { 066 return (String) params.get(name.toLowerCase()); 067 } 068 069 public void set(String name, String value) { 070 params.put(name.toLowerCase(), value); 071 } 072 073 public void remove(String name) { 074 params.remove(name.toLowerCase()); 075 } 076 077 public Enumeration getNames() { 078 return Collections.enumeration(params.keySet()); 079 } 080 081 /** 082 * String representation of this parameter list. 083 * 084 * @return 085 */ 086 public String toString() { 087 StringBuffer buf = new StringBuffer(params.size() << 4); 088 for (Iterator i = params.entrySet().iterator(); i.hasNext();) { 089 Map.Entry entry = (Map.Entry) i.next(); 090 buf.append("; ").append(entry.getKey()).append('='); 091 quote(buf, (String) entry.getValue()); 092 } 093 return buf.toString(); 094 } 095 096 private void quote(StringBuffer buf, String value) { 097 int length = value.length(); 098 boolean quote = false; 099 for (int i = 0; i < length; i++) { 100 if (MimeType.isSpecial(value.charAt(i))) { 101 quote = true; 102 break; 103 } 104 } 105 if (quote) { 106 buf.append('"'); 107 for (int i = 0; i < length; i++) { 108 char c = value.charAt(i); 109 if (c == '\\' || c == '"') { 110 buf.append('\\'); 111 } 112 buf.append(c); 113 } 114 buf.append('"'); 115 } else { 116 buf.append(value); 117 } 118 } 119 120 private static class RFC2045Parser { 121 private final String text; 122 private int index = 0; 123 124 private RFC2045Parser(String text) { 125 this.text = text; 126 } 127 128 /** 129 * Look the next ";" to start a parameter (skipping whitespace) 130 * 131 * @return 132 */ 133 private boolean hasMoreParams() throws MimeTypeParseException { 134 char c; 135 do { 136 if (index == text.length()) { 137 return false; 138 } 139 c = text.charAt(index++); 140 } while (Character.isWhitespace(c)); 141 if (c != ';') { 142 throw new MimeTypeParseException("Expected \";\" at " + (index - 1) + " in " + text); 143 } 144 return true; 145 } 146 147 private String expectAttribute() throws MimeTypeParseException { 148 char c; 149 do { 150 if (index == text.length()) { 151 throw new MimeTypeParseException("Expected attribute at " + (index - 1) + " in " + text); 152 } 153 c = text.charAt(index++); 154 } while (Character.isWhitespace(c)); 155 int start = index - 1; 156 while (index != text.length() && !MimeType.isSpecial(text.charAt(index))) { 157 index += 1; 158 } 159 return text.substring(start, index); 160 } 161 162 private void expectEquals() throws MimeTypeParseException { 163 char c; 164 do { 165 if (index == text.length()) { 166 throw new MimeTypeParseException("Expected \"=\" at " + (index - 1) + " in " + text); 167 } 168 c = text.charAt(index++); 169 } while (Character.isWhitespace(c)); 170 if (c != '=') { 171 throw new MimeTypeParseException("Expected \"=\" at " + (index - 1) + " in " + text); 172 } 173 } 174 175 private String expectValue() throws MimeTypeParseException { 176 char c; 177 do { 178 if (index == text.length()) { 179 throw new MimeTypeParseException("Expected value at " + (index - 1) + " in " + text); 180 } 181 c = text.charAt(index++); 182 } while (Character.isWhitespace(c)); 183 if (c == '"') { 184 // quoted-string 185 StringBuffer buf = new StringBuffer(); 186 while (true) { 187 if (index == text.length()) { 188 throw new MimeTypeParseException("Expected closing quote at " + (index - 1) + " in " + text); 189 } 190 c = text.charAt(index++); 191 if (c == '"') { 192 break; 193 } 194 if (c == '\\') { 195 if (index == text.length()) { 196 throw new MimeTypeParseException("Expected escaped char at " + (index - 1) + " in " + text); 197 } 198 c = text.charAt(index++); 199 } 200 buf.append(c); 201 } 202 return buf.toString(); 203 } else { 204 // token 205 int start = index - 1; 206 while (index != text.length() && !MimeType.isSpecial(text.charAt(index))) { 207 index += 1; 208 } 209 return text.substring(start, index); 210 } 211 } 212 } 213 }