Source Code Cross Referenced for EntityEnclosingMethod.java in  » Net » Apache-common-HttpClient » org » apache » commons » httpclient » methods » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » Apache common HttpClient » org.apache.commons.httpclient.methods 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java,v 1.39 2004/07/03 14:27:03 olegk Exp $
003:         * $Revision: 480424 $
004:         * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005:         *
006:         * ====================================================================
007:         *
008:         *  Licensed to the Apache Software Foundation (ASF) under one or more
009:         *  contributor license agreements.  See the NOTICE file distributed with
010:         *  this work for additional information regarding copyright ownership.
011:         *  The ASF licenses this file to You under the Apache License, Version 2.0
012:         *  (the "License"); you may not use this file except in compliance with
013:         *  the License.  You may obtain a copy of the License at
014:         *
015:         *      http://www.apache.org/licenses/LICENSE-2.0
016:         *
017:         *  Unless required by applicable law or agreed to in writing, software
018:         *  distributed under the License is distributed on an "AS IS" BASIS,
019:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020:         *  See the License for the specific language governing permissions and
021:         *  limitations under the License.
022:         * ====================================================================
023:         *
024:         * This software consists of voluntary contributions made by many
025:         * individuals on behalf of the Apache Software Foundation.  For more
026:         * information on the Apache Software Foundation, please see
027:         * <http://www.apache.org/>.
028:         *
029:         */
030:
031:        package org.apache.commons.httpclient.methods;
032:
033:        import java.io.IOException;
034:        import java.io.InputStream;
035:        import java.io.OutputStream;
036:        import java.io.UnsupportedEncodingException;
037:
038:        import org.apache.commons.httpclient.ChunkedOutputStream;
039:        import org.apache.commons.httpclient.Header;
040:        import org.apache.commons.httpclient.HttpConnection;
041:        import org.apache.commons.httpclient.HttpException;
042:        import org.apache.commons.httpclient.HttpState;
043:        import org.apache.commons.httpclient.HttpVersion;
044:        import org.apache.commons.httpclient.ProtocolException;
045:        import org.apache.commons.logging.Log;
046:        import org.apache.commons.logging.LogFactory;
047:
048:        /**
049:         * This abstract class serves as a foundation for all HTTP methods 
050:         * that can enclose an entity within requests 
051:         *
052:         * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
053:         * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
054:         *
055:         * @since 2.0beta1
056:         * @version $Revision: 480424 $
057:         */
058:        public abstract class EntityEnclosingMethod extends
059:                ExpectContinueMethod {
060:
061:            // ----------------------------------------- Static variables/initializers
062:
063:            /**
064:             * The content length will be calculated automatically. This implies
065:             * buffering of the content.
066:             * @deprecated Use {@link InputStreamRequestEntity#CONTENT_LENGTH_AUTO}.
067:             */
068:            public static final long CONTENT_LENGTH_AUTO = InputStreamRequestEntity.CONTENT_LENGTH_AUTO;
069:
070:            /**
071:             * The request will use chunked transfer encoding. Content length is not
072:             * calculated and the content is not buffered.<br>
073:             * @deprecated Use {@link #setContentChunked(boolean)}.
074:             */
075:            public static final long CONTENT_LENGTH_CHUNKED = -1;
076:
077:            /** LOG object for this class. */
078:            private static final Log LOG = LogFactory
079:                    .getLog(EntityEnclosingMethod.class);
080:
081:            /** The unbuffered request body, if any. */
082:            private InputStream requestStream = null;
083:
084:            /** The request body as string, if any. */
085:            private String requestString = null;
086:
087:            private RequestEntity requestEntity;
088:
089:            /** Counts how often the request was sent to the server. */
090:            private int repeatCount = 0;
091:
092:            /** The content length of the <code>requestBodyStream</code> or one of
093:             *  <code>CONTENT_LENGTH_AUTO</code> and <code>CONTENT_LENGTH_CHUNKED</code>.
094:             * 
095:             * @deprecated
096:             */
097:            private long requestContentLength = InputStreamRequestEntity.CONTENT_LENGTH_AUTO;
098:
099:            private boolean chunked = false;
100:
101:            // ----------------------------------------------------------- Constructors
102:
103:            /**
104:             * No-arg constructor.
105:             *
106:             * @since 2.0
107:             */
108:            public EntityEnclosingMethod() {
109:                super ();
110:                setFollowRedirects(false);
111:            }
112:
113:            /**
114:             * Constructor specifying a URI.
115:             *
116:             * @param uri either an absolute or relative URI
117:             *
118:             * @since 2.0
119:             */
120:            public EntityEnclosingMethod(String uri) {
121:                super (uri);
122:                setFollowRedirects(false);
123:            }
124:
125:            /**
126:             * Returns <tt>true</tt> if there is a request body to be sent.
127:             * 
128:             * <P>This method must be overridden by sub-classes that implement
129:             * alternative request content input methods
130:             * </p>
131:             * 
132:             * @return boolean
133:             * 
134:             * @since 2.0beta1
135:             */
136:            protected boolean hasRequestContent() {
137:                LOG.trace("enter EntityEnclosingMethod.hasRequestContent()");
138:                return (this .requestEntity != null)
139:                        || (this .requestStream != null)
140:                        || (this .requestString != null);
141:            }
142:
143:            /**
144:             * Clears the request body.
145:             * 
146:             * <p>This method must be overridden by sub-classes that implement
147:             * alternative request content input methods.</p>
148:             * 
149:             * @since 2.0beta1
150:             */
151:            protected void clearRequestBody() {
152:                LOG.trace("enter EntityEnclosingMethod.clearRequestBody()");
153:                this .requestStream = null;
154:                this .requestString = null;
155:                this .requestEntity = null;
156:            }
157:
158:            /**
159:             * Generates the request body.   
160:             * 
161:             * <p>This method must be overridden by sub-classes that implement
162:             * alternative request content input methods.</p>
163:             * 
164:             * @return request body as an array of bytes. If the request content 
165:             *          has not been set, returns <tt>null</tt>.
166:             * 
167:             * @since 2.0beta1
168:             */
169:            protected byte[] generateRequestBody() {
170:                LOG.trace("enter EntityEnclosingMethod.renerateRequestBody()");
171:                return null;
172:            }
173:
174:            protected RequestEntity generateRequestEntity() {
175:
176:                byte[] requestBody = generateRequestBody();
177:                if (requestBody != null) {
178:                    // use the request body, if it exists.
179:                    // this is just for backwards compatability
180:                    this .requestEntity = new ByteArrayRequestEntity(requestBody);
181:                } else if (this .requestStream != null) {
182:                    this .requestEntity = new InputStreamRequestEntity(
183:                            requestStream, requestContentLength);
184:                    this .requestStream = null;
185:                } else if (this .requestString != null) {
186:                    String charset = getRequestCharSet();
187:                    try {
188:                        this .requestEntity = new StringRequestEntity(
189:                                requestString, null, charset);
190:                    } catch (UnsupportedEncodingException e) {
191:                        if (LOG.isWarnEnabled()) {
192:                            LOG.warn(charset + " not supported");
193:                        }
194:                        try {
195:                            this .requestEntity = new StringRequestEntity(
196:                                    requestString, null, null);
197:                        } catch (UnsupportedEncodingException ignore) {
198:                        }
199:                    }
200:                }
201:
202:                return this .requestEntity;
203:            }
204:
205:            /**
206:             * Entity enclosing requests cannot be redirected without user intervention
207:             * according to RFC 2616.
208:             *
209:             * @return <code>false</code>.
210:             *
211:             * @since 2.0
212:             */
213:            public boolean getFollowRedirects() {
214:                return false;
215:            }
216:
217:            /**
218:             * Entity enclosing requests cannot be redirected without user intervention 
219:             * according to RFC 2616.
220:             *
221:             * @param followRedirects must always be <code>false</code>
222:             */
223:            public void setFollowRedirects(boolean followRedirects) {
224:                if (followRedirects == true) {
225:                    throw new IllegalArgumentException(
226:                            "Entity enclosing requests cannot be redirected without user intervention");
227:                }
228:                super .setFollowRedirects(false);
229:            }
230:
231:            /**
232:             * Sets length information about the request body.
233:             *
234:             * <p>
235:             * Note: If you specify a content length the request is unbuffered. This
236:             * prevents redirection and automatic retry if a request fails the first
237:             * time. This means that the HttpClient can not perform authorization
238:             * automatically but will throw an Exception. You will have to set the
239:             * necessary 'Authorization' or 'Proxy-Authorization' headers manually.
240:             * </p>
241:             *
242:             * @param length size in bytes or any of CONTENT_LENGTH_AUTO,
243:             *        CONTENT_LENGTH_CHUNKED. If number of bytes or CONTENT_LENGTH_CHUNKED
244:             *        is specified the content will not be buffered internally and the
245:             *        Content-Length header of the request will be used. In this case
246:             *        the user is responsible to supply the correct content length.
247:             *        If CONTENT_LENGTH_AUTO is specified the request will be buffered
248:             *        before it is sent over the network.
249:             * 
250:             * @deprecated Use {@link #setContentChunked(boolean)} or 
251:             * {@link #setRequestEntity(RequestEntity)}
252:             */
253:            public void setRequestContentLength(int length) {
254:                LOG
255:                        .trace("enter EntityEnclosingMethod.setRequestContentLength(int)");
256:                this .requestContentLength = length;
257:            }
258:
259:            /**
260:             * Returns the request's charset.  The charset is parsed from the request entity's 
261:             * content type, unless the content type header has been set manually. 
262:             * 
263:             * @see RequestEntity#getContentType()
264:             * 
265:             * @since 3.0
266:             */
267:            public String getRequestCharSet() {
268:                if (getRequestHeader("Content-Type") == null) {
269:                    // check the content type from request entity
270:                    // We can't call getRequestEntity() since it will probably call
271:                    // this method.
272:                    if (this .requestEntity != null) {
273:                        return getContentCharSet(new Header("Content-Type",
274:                                requestEntity.getContentType()));
275:                    } else {
276:                        return super .getRequestCharSet();
277:                    }
278:                } else {
279:                    return super .getRequestCharSet();
280:                }
281:            }
282:
283:            /**
284:             * Sets length information about the request body.
285:             *
286:             * <p>
287:             * Note: If you specify a content length the request is unbuffered. This
288:             * prevents redirection and automatic retry if a request fails the first
289:             * time. This means that the HttpClient can not perform authorization
290:             * automatically but will throw an Exception. You will have to set the
291:             * necessary 'Authorization' or 'Proxy-Authorization' headers manually.
292:             * </p>
293:             *
294:             * @param length size in bytes or any of CONTENT_LENGTH_AUTO,
295:             *        CONTENT_LENGTH_CHUNKED. If number of bytes or CONTENT_LENGTH_CHUNKED
296:             *        is specified the content will not be buffered internally and the
297:             *        Content-Length header of the request will be used. In this case
298:             *        the user is responsible to supply the correct content length.
299:             *        If CONTENT_LENGTH_AUTO is specified the request will be buffered
300:             *        before it is sent over the network.
301:             * 
302:             * @deprecated Use {@link #setContentChunked(boolean)} or 
303:             * {@link #setRequestEntity(RequestEntity)}
304:             */
305:            public void setRequestContentLength(long length) {
306:                LOG
307:                        .trace("enter EntityEnclosingMethod.setRequestContentLength(int)");
308:                this .requestContentLength = length;
309:            }
310:
311:            /**
312:             * Sets whether or not the content should be chunked.
313:             * 
314:             * @param chunked <code>true</code> if the content should be chunked
315:             * 
316:             * @since 3.0
317:             */
318:            public void setContentChunked(boolean chunked) {
319:                this .chunked = chunked;
320:            }
321:
322:            /**
323:             * Returns the length of the request body.
324:             *
325:             * @return number of bytes in the request body
326:             */
327:            protected long getRequestContentLength() {
328:                LOG
329:                        .trace("enter EntityEnclosingMethod.getRequestContentLength()");
330:
331:                if (!hasRequestContent()) {
332:                    return 0;
333:                }
334:                if (this .chunked) {
335:                    return -1;
336:                }
337:                if (this .requestEntity == null) {
338:                    this .requestEntity = generateRequestEntity();
339:                }
340:                return (this .requestEntity == null) ? 0 : this .requestEntity
341:                        .getContentLength();
342:            }
343:
344:            /**
345:             * Populates the request headers map to with additional 
346:             * {@link org.apache.commons.httpclient.Header headers} to be submitted to 
347:             * the given {@link HttpConnection}.
348:             *
349:             * <p>
350:             * This implementation adds tt>Content-Length</tt> or <tt>Transfer-Encoding</tt>
351:             * headers.
352:             * </p>
353:             *
354:             * <p>
355:             * Subclasses may want to override this method to to add additional
356:             * headers, and may choose to invoke this implementation (via
357:             * <tt>super</tt>) to add the "standard" headers.
358:             * </p>
359:             *
360:             * @param state the {@link HttpState state} information associated with this method
361:             * @param conn the {@link HttpConnection connection} used to execute
362:             *        this HTTP method
363:             *
364:             * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
365:             *                     can be recovered from.
366:             * @throws HttpException  if a protocol exception occurs. Usually protocol exceptions 
367:             *                    cannot be recovered from.
368:             *
369:             * @see #writeRequestHeaders
370:             * 
371:             * @since 3.0
372:             */
373:            protected void addRequestHeaders(HttpState state,
374:                    HttpConnection conn) throws IOException, HttpException {
375:                LOG
376:                        .trace("enter EntityEnclosingMethod.addRequestHeaders(HttpState, "
377:                                + "HttpConnection)");
378:
379:                super .addRequestHeaders(state, conn);
380:                addContentLengthRequestHeader(state, conn);
381:
382:                // only use the content type of the request entity if it has not already been
383:                // set manually
384:                if (getRequestHeader("Content-Type") == null) {
385:                    RequestEntity requestEntity = getRequestEntity();
386:                    if (requestEntity != null
387:                            && requestEntity.getContentType() != null) {
388:                        setRequestHeader("Content-Type", requestEntity
389:                                .getContentType());
390:                    }
391:                }
392:            }
393:
394:            /**
395:             * Generates <tt>Content-Length</tt> or <tt>Transfer-Encoding: Chunked</tt>
396:             * request header, as long as no <tt>Content-Length</tt> request header
397:             * already exists.
398:             *
399:             * @param state current state of http requests
400:             * @param conn the connection to use for I/O
401:             *
402:             * @throws IOException when errors occur reading or writing to/from the
403:             *         connection
404:             * @throws HttpException when a recoverable error occurs
405:             */
406:            protected void addContentLengthRequestHeader(HttpState state,
407:                    HttpConnection conn) throws IOException, HttpException {
408:                LOG
409:                        .trace("enter EntityEnclosingMethod.addContentLengthRequestHeader("
410:                                + "HttpState, HttpConnection)");
411:
412:                if ((getRequestHeader("content-length") == null)
413:                        && (getRequestHeader("Transfer-Encoding") == null)) {
414:                    long len = getRequestContentLength();
415:                    if (len < 0) {
416:                        if (getEffectiveVersion().greaterEquals(
417:                                HttpVersion.HTTP_1_1)) {
418:                            addRequestHeader("Transfer-Encoding", "chunked");
419:                        } else {
420:                            throw new ProtocolException(getEffectiveVersion()
421:                                    + " does not support chunk encoding");
422:                        }
423:                    } else {
424:                        addRequestHeader("Content-Length", String.valueOf(len));
425:                    }
426:                }
427:            }
428:
429:            /**
430:             * Sets the request body to be the specified inputstream.
431:             *
432:             * @param body Request body content as {@link java.io.InputStream}
433:             * 
434:             * @deprecated use {@link #setRequestEntity(RequestEntity)}
435:             */
436:            public void setRequestBody(InputStream body) {
437:                LOG
438:                        .trace("enter EntityEnclosingMethod.setRequestBody(InputStream)");
439:                clearRequestBody();
440:                this .requestStream = body;
441:            }
442:
443:            /**
444:             * Sets the request body to be the specified string.
445:             * The string will be submitted, using the encoding
446:             * specified in the Content-Type request header.<br>
447:             * Example: <code>setRequestHeader("Content-type", "text/xml; charset=UTF-8");</code><br>
448:             * Would use the UTF-8 encoding.
449:             * If no charset is specified, the 
450:             * {@link org.apache.commons.httpclient.HttpConstants#DEFAULT_CONTENT_CHARSET default}
451:             * content encoding is used (ISO-8859-1).
452:             *
453:             * @param body Request body content as a string
454:             * 
455:             * @deprecated use {@link #setRequestEntity(RequestEntity)}
456:             */
457:            public void setRequestBody(String body) {
458:                LOG.trace("enter EntityEnclosingMethod.setRequestBody(String)");
459:                clearRequestBody();
460:                this .requestString = body;
461:            }
462:
463:            /**
464:             * Writes the request body to the given {@link HttpConnection connection}.
465:             *
466:             * @param state the {@link HttpState state} information associated with this method
467:             * @param conn the {@link HttpConnection connection} used to execute
468:             *        this HTTP method
469:             *
470:             * @return <tt>true</tt>
471:             *
472:             * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
473:             *                     can be recovered from.
474:             * @throws HttpException  if a protocol exception occurs. Usually protocol exceptions 
475:             *                    cannot be recovered from.
476:             */
477:            protected boolean writeRequestBody(HttpState state,
478:                    HttpConnection conn) throws IOException, HttpException {
479:                LOG
480:                        .trace("enter EntityEnclosingMethod.writeRequestBody(HttpState, HttpConnection)");
481:
482:                if (!hasRequestContent()) {
483:                    LOG.debug("Request body has not been specified");
484:                    return true;
485:                }
486:                if (this .requestEntity == null) {
487:                    this .requestEntity = generateRequestEntity();
488:                }
489:                if (requestEntity == null) {
490:                    LOG.debug("Request body is empty");
491:                    return true;
492:                }
493:
494:                long contentLength = getRequestContentLength();
495:
496:                if ((this .repeatCount > 0) && !requestEntity.isRepeatable()) {
497:                    throw new ProtocolException(
498:                            "Unbuffered entity enclosing request can not be repeated.");
499:                }
500:
501:                this .repeatCount++;
502:
503:                OutputStream outstream = conn.getRequestOutputStream();
504:
505:                if (contentLength < 0) {
506:                    outstream = new ChunkedOutputStream(outstream);
507:                }
508:
509:                requestEntity.writeRequest(outstream);
510:
511:                // This is hardly the most elegant solution to closing chunked stream
512:                if (outstream instanceof  ChunkedOutputStream) {
513:                    ((ChunkedOutputStream) outstream).finish();
514:                }
515:
516:                outstream.flush();
517:
518:                LOG.debug("Request body sent");
519:                return true;
520:            }
521:
522:            /**
523:             * Recycles the HTTP method so that it can be used again.
524:             * Note that all of the instance variables will be reset
525:             * once this method has been called. This method will also
526:             * release the connection being used by this HTTP method.
527:             * 
528:             * @see #releaseConnection()
529:             * 
530:             * @deprecated no longer supported and will be removed in the future
531:             *             version of HttpClient
532:             */
533:            public void recycle() {
534:                LOG.trace("enter EntityEnclosingMethod.recycle()");
535:                clearRequestBody();
536:                this .requestContentLength = InputStreamRequestEntity.CONTENT_LENGTH_AUTO;
537:                this .repeatCount = 0;
538:                this .chunked = false;
539:                super .recycle();
540:            }
541:
542:            /**
543:             * @return Returns the requestEntity.
544:             * 
545:             * @since 3.0
546:             */
547:            public RequestEntity getRequestEntity() {
548:                return generateRequestEntity();
549:            }
550:
551:            /**
552:             * @param requestEntity The requestEntity to set.
553:             * 
554:             * @since 3.0
555:             */
556:            public void setRequestEntity(RequestEntity requestEntity) {
557:                clearRequestBody();
558:                this.requestEntity = requestEntity;
559:            }
560:
561:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.