![JAR search and dependency download from the Maven repository](/logo.png)
com.adobe.granite.httpcache.api.Headers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2012 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.granite.httpcache.api;
import org.apache.commons.lang.time.FastDateFormat;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
/**
* Container class for HTTP headers.
*/
public class Headers {
private final List entries = new ArrayList(16);
/** GMT Timezone. */
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
/** Date formatter. */
private static final FastDateFormat RFC1123 =
FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss z", GMT, Locale.US);
/**
* A header entry.
*/
public static class Entry {
public static enum Type {
STRING, LONG, INT
};
final String name;
final Type type;
private String s;
private long l;
private int i;
Entry(String name, String value) {
this.type = Type.STRING;
this.name = name;
this.s = value;
}
Entry(String name, long value) {
this.type = Type.LONG;
this.name = name;
this.l = value;
}
Entry(String name, int value) {
this.type = Type.INT;
this.name = name;
this.i = value;
}
/**
* Return the string representation of this entry's value. If the value's
* type is not STRING
, it is converted to a string as follows:
*
* - a long is formatted as a date in RFC1123 format
* - an integer is formatted as decimal number
*
*
* @return string representation
*/
public String getString() {
switch (type) {
case STRING:
return s;
case LONG:
return RFC1123.format(l);
case INT:
return String.valueOf(i);
default:
throw new InternalError("Illegal type: " + type);
}
}
/**
* Return a long value if the type is LONG, otherwise -1
*
* @return long
*/
public long getLong() {
if (type == Type.LONG) {
return l;
}
return -1;
}
/**
* Return an integer value if the type is INT, otherwise 0
*
* @return integer
*/
public int getInt() {
if (type == Type.INT) {
return i;
}
return 0;
}
/**
* Return the header type.
*
* @return type
*/
public Type getType() {
return type;
}
/**
* Return the header name.
*
* @return name
*/
public String getName() {
return name;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder(32);
s.append(name);
s.append(": ");
s.append(getString());
return s.toString();
}
}
/**
* Return the first header matching a given name.
*
* @param name
* name
* @return value of header or null
*/
public String getHeader(String name) {
for (int i = 0; i < entries.size(); i++) {
Entry e = entries.get(i);
if (e.name.equalsIgnoreCase(name)) {
return e.getString();
}
}
return null;
}
/**
* Return all headers matching a given name.
*
* @param name name
* @return matching values or null
*/
public String[] getHeaders(String name) {
ArrayList values = null;
for (int i = 0; i < entries.size(); i++) {
Entry e = entries.get(i);
if (e.name.equalsIgnoreCase(name)) {
if (values == null) {
values = new ArrayList();
}
values.add(e.getString());
}
}
if (values != null) {
String[] result = new String[values.size()];
return values.toArray(result);
}
return null;
}
/**
* Return the first header matching a given name.
*
* @param name name
* @return value of date header or -1
*/
public long getDateHeader(String name) {
for (int i = 0; i < entries.size(); i++) {
Entry e = entries.get(i);
if (e.name.equalsIgnoreCase(name)) {
return e.getLong();
}
}
return -1;
}
/**
* Return the first header matching a given name.
*
* @param name name
* @return value of date header or 0
*/
public int getIntHeader(String name) {
for (int i = 0; i < entries.size(); i++) {
Entry e = entries.get(i);
if (e.name.equalsIgnoreCase(name)) {
return e.getInt();
}
}
return 0;
}
/**
* Set a header. This will replace the first existing entry or add
* a new one.
*
* @param name name
* @param value value, if null
remove an existing header
*/
public void setHeader(String name, String value) {
if (value == null) {
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).name.equalsIgnoreCase(name)) {
entries.remove(i);
}
}
return;
}
setHeader(new Entry(name, value));
}
/**
* Set a header. This will replace the first existing entry or add
* a new one.
*
* @param name name
* @param value value
*/
public void setHeader(String name, long value) {
setHeader(new Entry(name, value));
}
/**
* Set a header. This will replace the first existing entry or add
* a new one.
*
* @param name name
* @param value value
*/
public void setHeader(String name, int value) {
setHeader(new Entry(name, value));
}
private void setHeader(Entry e) {
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).name.equalsIgnoreCase(e.name)) {
entries.set(i, e);
return;
}
}
entries.add(e);
}
/**
* Add a header.
*
* @param name name
* @param value value
*/
public void addHeader(String name, String value) {
entries.add(new Entry(name, value));
}
/**
* Add a header.
*
* @param name name
* @param value value
*/
public void addHeader(String name, long value) {
entries.add(new Entry(name, value));
}
/**
* Add a header.
*
* @param name name
* @param value value
*/
public void addHeader(String name, int value) {
entries.add(new Entry(name, value));
}
/**
* Return all entries.
*
* @return entries
*/
public Entry[] getEntries() {
Entry[] result = new Entry[entries.size()];
entries.toArray(result);
return result;
}
//----------------------------------------------------------- Serialization
// TODO: should the serialization format be customizable?
/**
* Store headers to an output stream.
*
* @param out output stream
* @throws java.io.IOException if an I/O error occurs
*/
public void save(OutputStream out) throws IOException {
// Store data in a byte array first
ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
writeShort(bout, entries.size());
for (int i = 0; i < entries.size(); i++) {
Entry e = entries.get(i);
writeString(bout, e.name);
switch (e.type) {
case STRING:
bout.write('S');
writeString(bout, e.getString());
break;
case LONG:
bout.write('L');
writeLong(bout, e.getLong());
break;
case INT:
bout.write('I');
writeInt(bout, e.getInt());
break;
default:
throw new InternalError("Illegal type: " + e.type);
}
}
out.write(bout.toByteArray());
}
private static void writeShort(OutputStream out, int n) throws IOException {
if (n > 65535) {
throw new IOException("Number too big to be saved as short: " + n);
}
out.write((n >>> 8) & 0xFF);
out.write((n >>> 0) & 0xFF);
}
private static void writeString(OutputStream out, String s) throws IOException {
byte[] b = s.getBytes("8859_1");
writeShort(out, b.length);
out.write(b);
}
private static void writeInt(OutputStream out, int n) throws IOException {
out.write((n >>> 24) & 0xff);
out.write((n >>> 16) & 0xff);
out.write((n >>> 8) & 0xff);
out.write((n >>> 0) & 0xff);
}
private static void writeLong(OutputStream out, long l) throws IOException {
writeInt(out, (int) (l >>> 32));
writeInt(out, (int) l & 0xffffffff);
}
/**
* Load stored headers from an input stream.
*
* @param in input stream
* @throws java.io.IOException if an I/O error occurs
*/
public void load(InputStream in) throws IOException {
int count = readUnsignedShort(in);
for (int i = 0; i < count; i++) {
String name = readString(in);
char ch = (char) in.read();
switch (ch) {
case 'S':
addHeader(name, readString(in));
break;
case 'L':
addHeader(name, readLong(in));
break;
case 'I':
addHeader(name, readInt(in));
break;
default:
throw new InternalError("Illegal type: " + ch);
}
}
}
private static int readUnsignedShort(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0) {
throw new EOFException();
}
return (ch1 << 8) + (ch2 << 0);
}
private static int readInt(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) {
throw new EOFException();
}
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
private static long readLong(InputStream in) throws IOException {
long h = readInt(in) & 0xffffffffL;
long l = readInt(in) & 0xffffffffL;
return h << 32 | l;
}
private static String readString(InputStream in) throws IOException {
byte[] b = new byte[readUnsignedShort(in)];
int off = 0;
while (off < b.length) {
int len = in.read(b, off, b.length - off);
if (len == -1) {
throw new EOFException();
}
off += len;
}
return new String(b, "8859_1");
}
@Override
public String toString() {
StringBuilder s = new StringBuilder(256);
for (Entry e : entries) {
s.append(e.toString());
s.append("\r\n");
}
return s.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy