001package org.apache.maven.wagon.providers.webdav; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.commons.httpclient.Header; 023import org.apache.commons.httpclient.params.HttpMethodParams; 024 025import java.util.ArrayList; 026import java.util.LinkedHashMap; 027import java.util.List; 028import java.util.Map; 029import java.util.Properties; 030import java.util.regex.Matcher; 031import java.util.regex.Pattern; 032 033/** 034 * 035 */ 036public class HttpMethodConfiguration 037{ 038 039 public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; 040 041 private static final String COERCE_PATTERN = "%(\\w+),(.+)"; 042 043 private Boolean useDefaultHeaders; 044 045 private Properties headers = new Properties(); 046 047 private Properties params = new Properties(); 048 049 private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT; 050 051 public boolean isUseDefaultHeaders() 052 { 053 return useDefaultHeaders == null ? true : useDefaultHeaders.booleanValue(); 054 } 055 056 public HttpMethodConfiguration setUseDefaultHeaders( boolean useDefaultHeaders ) 057 { 058 this.useDefaultHeaders = Boolean.valueOf( useDefaultHeaders ); 059 return this; 060 } 061 062 public Boolean getUseDefaultHeaders() 063 { 064 return useDefaultHeaders; 065 } 066 067 public HttpMethodConfiguration addHeader( String header, String value ) 068 { 069 headers.setProperty( header, value ); 070 return this; 071 } 072 073 public Properties getHeaders() 074 { 075 return headers; 076 } 077 078 public HttpMethodConfiguration setHeaders( Properties headers ) 079 { 080 this.headers = headers; 081 return this; 082 } 083 084 public HttpMethodConfiguration addParam( String param, String value ) 085 { 086 params.setProperty( param, value ); 087 return this; 088 } 089 090 public Properties getParams() 091 { 092 return params; 093 } 094 095 public HttpMethodConfiguration setParams( Properties params ) 096 { 097 this.params = params; 098 return this; 099 } 100 101 public int getConnectionTimeout() 102 { 103 return connectionTimeout; 104 } 105 106 public HttpMethodConfiguration setConnectionTimeout( int connectionTimeout ) 107 { 108 this.connectionTimeout = connectionTimeout; 109 return this; 110 } 111 112 public HttpMethodParams asMethodParams( HttpMethodParams defaults ) 113 { 114 if ( !hasParams() ) 115 { 116 return null; 117 } 118 119 HttpMethodParams p = new HttpMethodParams(); 120 p.setDefaults( defaults ); 121 122 fillParams( p ); 123 124 return p; 125 } 126 127 private boolean hasParams() 128 { 129 if ( connectionTimeout < 1 && params == null ) 130 { 131 return false; 132 } 133 134 return true; 135 } 136 137 private void fillParams( HttpMethodParams p ) 138 { 139 if ( !hasParams() ) 140 { 141 return; 142 } 143 144 if ( connectionTimeout > 0 ) 145 { 146 p.setSoTimeout( connectionTimeout ); 147 } 148 149 if ( params != null ) 150 { 151 Pattern coercePattern = Pattern.compile( COERCE_PATTERN ); 152 153 for ( Map.Entry<Object, Object> entry : params.entrySet() ) 154 { 155 String key = (String) entry.getKey(); 156 String value = (String) entry.getValue(); 157 158 Matcher matcher = coercePattern.matcher( value ); 159 if ( matcher.matches() ) 160 { 161 char type = matcher.group( 1 ).charAt( 0 ); 162 value = matcher.group( 2 ); 163 164 // CHECKSTYLE_OFF: AvoidNestedBlocks 165 switch ( type ) 166 { 167 case 'i': 168 p.setIntParameter( key, Integer.parseInt( value ) ); 169 break; 170 171 case 'd': 172 p.setDoubleParameter( key, Double.parseDouble( value ) ); 173 break; 174 175 case 'l': 176 p.setLongParameter( key, Long.parseLong( value ) ); 177 break; 178 179 case 'b': 180 p.setBooleanParameter( key, Boolean.valueOf( value ).booleanValue() ); 181 break; 182 183 case 'c': 184 { 185 String[] entries = value.split( "," ); 186 List<String> collection = new ArrayList<String>(); 187 for ( String e : entries ) 188 { 189 collection.add( e.trim() ); 190 } 191 192 p.setParameter( key, collection ); 193 break; 194 } 195 case 'm': 196 { 197 String[] entries = value.split( "," ); 198 199 Map<String, String> map = new LinkedHashMap<String, String>(); 200 for ( String e : entries ) 201 { 202 int idx = e.indexOf( "=>" ); 203 if ( idx < 1 ) 204 { 205 break; 206 } 207 208 String mapKey = e.substring( 0, idx ); 209 String mapVal = e.substring( idx + 1, e.length() ); 210 map.put( mapKey.trim(), mapVal.trim() ); 211 } 212 213 p.setParameter( key, map ); 214 break; 215 } 216 default: 217 } 218 // CHECKSTYLE_ON: AvoidNestedBlocks 219 } 220 else 221 { 222 p.setParameter( key, value ); 223 } 224 } 225 } 226 } 227 228 public Header[] asRequestHeaders() 229 { 230 if ( headers == null ) 231 { 232 return new Header[0]; 233 } 234 235 Header[] result = new Header[headers.size()]; 236 237 int index = 0; 238 for ( Map.Entry<Object, Object> entry : headers.entrySet() ) 239 { 240 String key = (String) entry.getKey(); 241 String value = (String) entry.getValue(); 242 243 Header header = new Header( key, value ); 244 result[index++] = header; 245 } 246 247 return result; 248 } 249 250 private HttpMethodConfiguration copy() 251 { 252 HttpMethodConfiguration copy = new HttpMethodConfiguration(); 253 254 copy.setConnectionTimeout( getConnectionTimeout() ); 255 if ( getHeaders() != null ) 256 { 257 copy.setHeaders( getHeaders() ); 258 } 259 260 if ( getParams() != null ) 261 { 262 copy.setParams( getParams() ); 263 } 264 265 copy.setUseDefaultHeaders( isUseDefaultHeaders() ); 266 267 return copy; 268 } 269 270 public static HttpMethodConfiguration merge( HttpMethodConfiguration defaults, HttpMethodConfiguration base, 271 HttpMethodConfiguration local ) 272 { 273 HttpMethodConfiguration result = merge( defaults, base ); 274 return merge( result, local ); 275 } 276 277 public static HttpMethodConfiguration merge( HttpMethodConfiguration base, HttpMethodConfiguration local ) 278 { 279 if ( base == null && local == null ) 280 { 281 return null; 282 } 283 else if ( base == null ) 284 { 285 return local; 286 } 287 else if ( local == null ) 288 { 289 return base; 290 } 291 else 292 { 293 HttpMethodConfiguration result = base.copy(); 294 295 if ( local.getConnectionTimeout() != DEFAULT_CONNECTION_TIMEOUT ) 296 { 297 result.setConnectionTimeout( local.getConnectionTimeout() ); 298 } 299 300 if ( local.getHeaders() != null ) 301 { 302 result.getHeaders().putAll( local.getHeaders() ); 303 } 304 305 if ( local.getParams() != null ) 306 { 307 result.getParams().putAll( local.getParams() ); 308 } 309 310 if ( local.getUseDefaultHeaders() != null ) 311 { 312 result.setUseDefaultHeaders( local.isUseDefaultHeaders() ); 313 } 314 315 return result; 316 } 317 } 318 319}