001 package org.apache.fulcrum.parser; 002 003 004 /* 005 * Licensed to the Apache Software Foundation (ASF) under one 006 * or more contributor license agreements. See the NOTICE file 007 * distributed with this work for additional information 008 * regarding copyright ownership. The ASF licenses this file 009 * to you under the Apache License, Version 2.0 (the 010 * "License"); you may not use this file except in compliance 011 * with the License. You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, 016 * software distributed under the License is distributed on an 017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 018 * KIND, either express or implied. See the License for the 019 * specific language governing permissions and limitations 020 * under the License. 021 */ 022 023 024 import java.util.List; 025 026 import javax.servlet.http.HttpServletRequest; 027 028 import org.apache.avalon.framework.configuration.Configurable; 029 import org.apache.avalon.framework.configuration.Configuration; 030 import org.apache.avalon.framework.configuration.ConfigurationException; 031 import org.apache.avalon.framework.logger.AbstractLogEnabled; 032 import org.apache.avalon.framework.logger.LogEnabled; 033 import org.apache.avalon.framework.service.ServiceException; 034 import org.apache.avalon.framework.service.ServiceManager; 035 import org.apache.avalon.framework.service.Serviceable; 036 import org.apache.commons.lang.StringUtils; 037 import org.apache.fulcrum.pool.PoolException; 038 import org.apache.fulcrum.pool.PoolService; 039 import org.apache.fulcrum.upload.UploadService; 040 041 042 /** 043 * The DefaultParserService provides the efault implementation 044 * of a {@link ParserService}. 045 * 046 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> 047 * @version $Id: BaseValueParser.java 542062 2007-05-28 00:29:43Z seade $ 048 */ 049 public class DefaultParserService 050 extends AbstractLogEnabled 051 implements ParserService, 052 Configurable, Serviceable 053 { 054 /** The folding from the configuration */ 055 private int folding = URL_CASE_FOLDING_NONE; 056 057 /** The automaticUpload setting from the configuration */ 058 private boolean automaticUpload = AUTOMATIC_DEFAULT; 059 060 /** 061 * The parameter encoding to use when parsing parameter strings 062 */ 063 private String parameterEncoding = PARAMETER_ENCODING_DEFAULT; 064 065 /** 066 * The upload service component to use 067 */ 068 private UploadService uploadService = null; 069 070 /** 071 * The pool service component to use 072 */ 073 private PoolService poolService = null; 074 075 /** 076 * Get the character encoding that will be used by this ValueParser. 077 */ 078 public String getParameterEncoding() 079 { 080 return parameterEncoding; 081 } 082 083 /** 084 * Trims the string data and applies the conversion specified in 085 * the property given by URL_CASE_FOLDING. It returns a new 086 * string so that it does not destroy the value data. 087 * 088 * @param value A String to be processed. 089 * @return A new String converted to lowercase and trimmed. 090 */ 091 public String convert(String value) 092 { 093 return convertAndTrim(value); 094 } 095 096 /** 097 * Convert a String value according to the url-case-folding property. 098 * 099 * @param value the String to convert 100 * 101 * @return a new String. 102 * 103 */ 104 public String convertAndTrim(String value) 105 { 106 return convertAndTrim(value, getUrlFolding()); 107 } 108 109 /** 110 * A static version of the convert method, which 111 * trims the string data and applies the conversion specified in 112 * the property given by URL_CASE_FOLDING. It returns a new 113 * string so that it does not destroy the value data. 114 * 115 * @param value A String to be processed. 116 * @return A new String converted to lowercase and trimmed. 117 */ 118 public String convertAndTrim(String value, int fold) 119 { 120 if(value == null) return ""; 121 122 String tmp = value.trim(); 123 124 switch (fold) 125 { 126 case URL_CASE_FOLDING_NONE: 127 { 128 break; 129 } 130 131 case URL_CASE_FOLDING_LOWER: 132 { 133 tmp = tmp.toLowerCase(); 134 break; 135 } 136 137 case URL_CASE_FOLDING_UPPER: 138 { 139 tmp = tmp.toUpperCase(); 140 break; 141 } 142 143 default: 144 { 145 getLogger().error("Passed " + fold + " as fold rule, which is illegal!"); 146 break; 147 } 148 } 149 return tmp; 150 } 151 152 /** 153 * Gets the folding value from the configuration 154 * 155 * @return The current Folding Value 156 */ 157 public int getUrlFolding() 158 { 159 return folding; 160 } 161 162 /** 163 * Gets the automaticUpload value from the configuration 164 * 165 * @return The current automaticUpload Value 166 */ 167 public boolean getAutomaticUpload() 168 { 169 return automaticUpload; 170 } 171 172 /** 173 * Use the UploadService if available to parse the given request 174 * for uploaded files 175 * 176 * @return A list of {@link org.apache.commons.upload.FileItem}s 177 * 178 * @throws ServiceException if parsing fails or the UploadService 179 * is not available 180 */ 181 public List parseUpload(HttpServletRequest request) throws ServiceException 182 { 183 if (uploadService == null) 184 { 185 throw new ServiceException(ParserService.ROLE, "UploadService is not available."); 186 } 187 else 188 { 189 return uploadService.parseRequest(request); 190 } 191 } 192 193 /** 194 * Get a {@link ValueParser} instance from the service. Use the 195 * given Class to create the object. 196 * 197 * @return An object that implements ValueParser 198 * 199 * @throws InstantiationException if the instance could not be created 200 */ 201 public ValueParser getParser(Class ppClass) throws InstantiationException 202 { 203 ValueParser vp = null; 204 205 try 206 { 207 vp = (ValueParser) poolService.getInstance(ppClass); 208 209 if (vp instanceof ParserServiceSupport) 210 { 211 ((ParserServiceSupport)vp).setParserService(this); 212 } 213 214 if (vp instanceof LogEnabled) 215 { 216 ((LogEnabled)vp).enableLogging(getLogger().getChildLogger(ppClass.getName())); 217 } 218 219 } 220 catch (PoolException pe) 221 { 222 throw new InstantiationException("Parser class '" + ppClass + "' is illegal. " + pe.getMessage()); 223 } 224 catch (ClassCastException x) 225 { 226 throw new InstantiationException("Parser class '" + ppClass + "' is illegal. " + x.getMessage()); 227 } 228 229 return vp; 230 } 231 232 /** 233 * Return a used Parser to the service. This allows for 234 * pooling and recycling 235 * 236 * @param parser 237 */ 238 public void putParser(ValueParser parser) 239 { 240 parser.clear(); 241 poolService.putInstance(parser); 242 } 243 244 /** 245 * Avalon component lifecycle method 246 */ 247 public void configure(Configuration conf) throws ConfigurationException 248 { 249 if (folding == URL_CASE_FOLDING_UNSET) 250 { 251 String foldString = conf.getChild(URL_CASE_FOLDING_KEY).getValue(URL_CASE_FOLDING_NONE_VALUE).toLowerCase(); 252 253 folding = URL_CASE_FOLDING_NONE; 254 255 getLogger().debug("Setting folding from " + foldString); 256 257 if (StringUtils.isNotEmpty(foldString)) 258 { 259 if (foldString.equals(URL_CASE_FOLDING_NONE_VALUE)) 260 { 261 folding = URL_CASE_FOLDING_NONE; 262 } 263 else if (foldString.equals(URL_CASE_FOLDING_LOWER_VALUE)) 264 { 265 folding = URL_CASE_FOLDING_LOWER; 266 } 267 else if (foldString.equals(URL_CASE_FOLDING_UPPER_VALUE)) 268 { 269 folding = URL_CASE_FOLDING_UPPER; 270 } 271 else 272 { 273 getLogger().error("Got " + foldString + " from " + URL_CASE_FOLDING_KEY + " property, which is illegal!"); 274 throw new ConfigurationException("Value " + foldString + " is illegal!"); 275 } 276 } 277 } 278 279 parameterEncoding = conf.getChild(PARAMETER_ENCODING_KEY) 280 .getValue(PARAMETER_ENCODING_DEFAULT).toLowerCase(); 281 282 automaticUpload = conf.getAttributeAsBoolean( 283 AUTOMATIC_KEY, 284 AUTOMATIC_DEFAULT); 285 } 286 287 // ---------------- Avalon Lifecycle Methods --------------------- 288 /** 289 * Avalon component lifecycle method 290 */ 291 public void service(ServiceManager manager) throws ServiceException 292 { 293 if (manager.hasService(UploadService.ROLE)) 294 { 295 uploadService = (UploadService)manager.lookup(UploadService.ROLE); 296 } 297 else 298 { 299 /* 300 * Automatic parsing of uploaded file items was requested but no 301 * UploadService is available 302 */ 303 if (getAutomaticUpload()) 304 { 305 throw new ServiceException(ParserService.ROLE, 306 AUTOMATIC_KEY + " = true requires " + 307 UploadService.ROLE + " to be available"); 308 } 309 } 310 311 if (manager.hasService(PoolService.ROLE)) 312 { 313 poolService = (PoolService)manager.lookup(PoolService.ROLE); 314 } 315 else 316 { 317 throw new ServiceException(ParserService.ROLE, 318 "Service requires " + 319 PoolService.ROLE + " to be available"); 320 } 321 } 322 }