001package org.apache.maven.wagon.shared.http4; 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.http.Header; 023import org.apache.http.message.BasicHeader; 024import org.apache.http.params.BasicHttpParams; 025import org.apache.http.params.CoreConnectionPNames; 026import org.apache.http.params.DefaultedHttpParams; 027import org.apache.http.params.HttpParams; 028import org.apache.maven.wagon.Wagon; 029 030import java.util.ArrayList; 031import java.util.Iterator; 032import java.util.LinkedHashMap; 033import java.util.List; 034import java.util.Map; 035import java.util.Properties; 036import java.util.regex.Matcher; 037import java.util.regex.Pattern; 038 039public class HttpMethodConfiguration 040{ 041 042 private static final String COERCE_PATTERN = "%(\\w+),(.+)"; 043 044 private Boolean useDefaultHeaders; 045 046 private Properties headers = new Properties(); 047 048 private Properties params = new Properties(); 049 050 private int connectionTimeout = Wagon.DEFAULT_CONNECTION_TIMEOUT; 051 052 private int readTimeout = 053 Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) ); 054 055 private boolean usePreemptive = false; 056 057 public boolean isUseDefaultHeaders() 058 { 059 return useDefaultHeaders == null || useDefaultHeaders.booleanValue(); 060 } 061 062 public HttpMethodConfiguration setUseDefaultHeaders( boolean useDefaultHeaders ) 063 { 064 this.useDefaultHeaders = Boolean.valueOf( useDefaultHeaders ); 065 return this; 066 } 067 068 public Boolean getUseDefaultHeaders() 069 { 070 return useDefaultHeaders; 071 } 072 073 public HttpMethodConfiguration addHeader( String header, String value ) 074 { 075 headers.setProperty( header, value ); 076 return this; 077 } 078 079 public Properties getHeaders() 080 { 081 return headers; 082 } 083 084 public HttpMethodConfiguration setHeaders( Properties headers ) 085 { 086 this.headers = headers; 087 return this; 088 } 089 090 public HttpMethodConfiguration addParam( String param, String value ) 091 { 092 params.setProperty( param, value ); 093 return this; 094 } 095 096 public Properties getParams() 097 { 098 return params; 099 } 100 101 public HttpMethodConfiguration setParams( Properties params ) 102 { 103 this.params = params; 104 return this; 105 } 106 107 public int getConnectionTimeout() 108 { 109 return connectionTimeout; 110 } 111 112 public HttpMethodConfiguration setConnectionTimeout( int connectionTimeout ) 113 { 114 this.connectionTimeout = connectionTimeout; 115 return this; 116 } 117 118 public int getReadTimeout() 119 { 120 return readTimeout; 121 } 122 123 public HttpMethodConfiguration setReadTimeout( int readTimeout ) 124 { 125 this.readTimeout = readTimeout; 126 return this; 127 } 128 129 public HttpParams asMethodParams( HttpParams defaults ) 130 { 131 if ( !hasParams() ) 132 { 133 return null; 134 } 135 136 DefaultedHttpParams p = new DefaultedHttpParams( new BasicHttpParams(), defaults ); 137 138 fillParams( p ); 139 140 return p; 141 } 142 143 private boolean hasParams() 144 { 145 if ( connectionTimeout < 1 && params == null && readTimeout < 1 ) 146 { 147 return false; 148 } 149 150 return true; 151 } 152 153 public boolean isUsePreemptive() 154 { 155 return usePreemptive; 156 } 157 158 public HttpMethodConfiguration setUsePreemptive( boolean usePreemptive ) 159 { 160 this.usePreemptive = usePreemptive; 161 return this; 162 } 163 164 private void fillParams( HttpParams p ) 165 { 166 if ( !hasParams() ) 167 { 168 return; 169 } 170 171 if ( connectionTimeout > 0 ) 172 { 173 p.setParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout ); 174 } 175 176 if ( readTimeout > 0 ) 177 { 178 p.setParameter( CoreConnectionPNames.SO_TIMEOUT, readTimeout ); 179 } 180 181 if ( params != null ) 182 { 183 Pattern coercePattern = Pattern.compile( COERCE_PATTERN ); 184 185 for ( Iterator<?> it = params.entrySet().iterator(); it.hasNext(); ) 186 { 187 Map.Entry<String, String> entry = (Map.Entry) it.next(); 188 189 String key = entry.getKey(); 190 String value = entry.getValue(); 191 192 Matcher matcher = coercePattern.matcher( value ); 193 if ( matcher.matches() ) 194 { 195 char type = matcher.group( 1 ).charAt( 0 ); 196 value = matcher.group( 2 ); 197 198 switch ( type ) 199 { 200 case 'i': 201 { 202 p.setIntParameter( key, Integer.parseInt( value ) ); 203 break; 204 } 205 case 'd': 206 { 207 p.setDoubleParameter( key, Double.parseDouble( value ) ); 208 break; 209 } 210 case 'l': 211 { 212 p.setLongParameter( key, Long.parseLong( value ) ); 213 break; 214 } 215 case 'b': 216 { 217 p.setBooleanParameter( key, Boolean.valueOf( value ).booleanValue() ); 218 break; 219 } 220 case 'c': 221 { 222 String[] entries = value.split( "," ); 223 List<String> collection = new ArrayList<String>(); 224 for ( int i = 0; i < entries.length; i++ ) 225 { 226 collection.add( entries[i].trim() ); 227 } 228 229 p.setParameter( key, collection ); 230 break; 231 } 232 case 'm': 233 { 234 String[] entries = value.split( "," ); 235 236 Map<String, String> map = new LinkedHashMap<String, String>(); 237 for ( int i = 0; i < entries.length; i++ ) 238 { 239 int idx = entries[i].indexOf( "=>" ); 240 if ( idx < 1 ) 241 { 242 break; 243 } 244 245 String mapKey = entries[i].substring( 0, idx ); 246 String mapVal = entries[i].substring( idx + 1, entries[i].length() ); 247 map.put( mapKey.trim(), mapVal.trim() ); 248 } 249 250 p.setParameter( key, map ); 251 break; 252 } 253 } 254 } 255 else 256 { 257 p.setParameter( key, value ); 258 } 259 } 260 } 261 } 262 263 public Header[] asRequestHeaders() 264 { 265 if ( headers == null ) 266 { 267 return new Header[0]; 268 } 269 270 Header[] result = new Header[headers.size()]; 271 272 int index = 0; 273 for ( Iterator<?> it = headers.entrySet().iterator(); it.hasNext(); ) 274 { 275 Map.Entry<String, String> entry = (Map.Entry) it.next(); 276 277 String key = entry.getKey(); 278 String value = entry.getValue(); 279 280 Header header = new BasicHeader( key, value ); 281 result[index++] = header; 282 } 283 284 return result; 285 } 286 287 private HttpMethodConfiguration copy() 288 { 289 HttpMethodConfiguration copy = new HttpMethodConfiguration(); 290 291 copy.setConnectionTimeout( getConnectionTimeout() ); 292 copy.setReadTimeout( getReadTimeout() ); 293 if ( getHeaders() != null ) 294 { 295 copy.setHeaders( getHeaders() ); 296 } 297 298 if ( getParams() != null ) 299 { 300 copy.setParams( getParams() ); 301 } 302 303 copy.setUseDefaultHeaders( isUseDefaultHeaders() ); 304 305 return copy; 306 } 307 308 public static HttpMethodConfiguration merge( HttpMethodConfiguration defaults, HttpMethodConfiguration base, 309 HttpMethodConfiguration local ) 310 { 311 HttpMethodConfiguration result = merge( defaults, base ); 312 return merge( result, local ); 313 } 314 315 public static HttpMethodConfiguration merge( HttpMethodConfiguration base, HttpMethodConfiguration local ) 316 { 317 if ( base == null && local == null ) 318 { 319 return null; 320 } 321 else if ( base == null ) 322 { 323 return local; 324 } 325 else if ( local == null ) 326 { 327 return base; 328 } 329 else 330 { 331 HttpMethodConfiguration result = base.copy(); 332 333 if ( local.getConnectionTimeout() != Wagon.DEFAULT_CONNECTION_TIMEOUT ) 334 { 335 result.setConnectionTimeout( local.getConnectionTimeout() ); 336 } 337 338 if ( local.getReadTimeout() != Wagon.DEFAULT_READ_TIMEOUT ) 339 { 340 result.setReadTimeout( local.getReadTimeout() ); 341 } 342 343 if ( local.getHeaders() != null ) 344 { 345 result.getHeaders().putAll( local.getHeaders() ); 346 } 347 348 if ( local.getParams() != null ) 349 { 350 result.getParams().putAll( local.getParams() ); 351 } 352 353 if ( local.getUseDefaultHeaders() != null ) 354 { 355 result.setUseDefaultHeaders( local.isUseDefaultHeaders() ); 356 } 357 358 return result; 359 } 360 } 361 362}