001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009 Sun Microsystems Inc. 015 * Portions Copyright 2010–2011 ApexIdentity Inc. 016 * Portions Copyright 2011-2014 ForgeRock AS. 017 */ 018 019package org.forgerock.openig.http; 020 021import java.io.Closeable; 022import java.io.IOException; 023 024import org.forgerock.openig.io.BranchingInputStream; 025 026/** 027 * Elements common to requests and responses. 028 * 029 * @param <T> 030 * The sub-type of this message. 031 */ 032public abstract class Message<T extends Message<T>> implements Closeable { 033 034 /** Message entity body. */ 035 private final Entity entity = new Entity(this); 036 037 /** Message header fields. */ 038 private final Headers headers = new Headers(); 039 040 /** Protocol version. Default: {@code HTTP/1.1}. */ 041 private String version = "HTTP/1.1"; 042 043 Message() { 044 // Hidden constructor. 045 } 046 047 /** 048 * Returns the entity. 049 * 050 * @return The entity. 051 */ 052 public final Entity getEntity() { 053 return entity; 054 } 055 056 /** 057 * Returns the headers. 058 * 059 * @return The headers. 060 */ 061 public final Headers getHeaders() { 062 prepareHeaders(headers); 063 return headers; 064 } 065 066 /** 067 * Update the headers if needed. 068 */ 069 void prepareHeaders(final Headers headers) { 070 // Nothing to do. 071 } 072 073 /** 074 * Returns the protocol version. Default: {@code HTTP/1.1}. 075 * 076 * @return The protocol version. 077 */ 078 public final String getVersion() { 079 return version; 080 } 081 082 /** 083 * Sets the content of the entity to the provided value. Calling this method 084 * will close any existing streams associated with the entity. May also set 085 * the {@code Content-Length} header, overwriting any existing header. 086 * <p> 087 * This method is intended mostly as a convenience method within scripts. 088 * The parameter will be handled depending on its type as follows: 089 * <ul> 090 * <li>{@code BranchingInputStream} - equivalent to calling 091 * {@link Entity#setRawInputStream} 092 * <li>{@code byte[]} - equivalent to calling {@link Entity#setBytes} 093 * <li>{@code String} - equivalent to calling {@link Entity#setString} 094 * <li>{@code Object} - equivalent to calling {@link Entity#setJson}. 095 * </ul> 096 * <p> 097 * Note: This method does not attempt to encode the entity based-on any 098 * codings specified in the {@code Content-Encoding} header. 099 * 100 * @param o 101 * The object whose value should be stored in the entity. 102 * @return This message. 103 * @throws IOException 104 * If an IO error occurred while reading/mapping the content. 105 */ 106 public final T setEntity(Object o) throws IOException { 107 if (o instanceof BranchingInputStream) { 108 entity.setRawInputStream((BranchingInputStream) o); 109 } else if (o instanceof byte[]) { 110 entity.setBytes((byte[]) o); 111 } else if (o instanceof String) { 112 entity.setString((String) o); 113 } else { 114 entity.setJson(o); 115 } 116 return thisMessage(); 117 } 118 119 /** 120 * Sets the protocol version. Default: {@code HTTP/1.1}. 121 * 122 * @param version 123 * The protocol version. 124 * @return This message. 125 */ 126 public final T setVersion(final String version) { 127 this.version = version; 128 return thisMessage(); 129 } 130 131 /** 132 * Closes all resources associated with the entity. Any open streams will be 133 * closed, and the underlying content reset back to a zero length. 134 * 135 * @see Entity#close() 136 */ 137 @Override 138 public void close() { 139 entity.close(); 140 } 141 142 abstract T thisMessage(); 143}