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 2010–2011 ApexIdentity Inc.
015 * Portions Copyright 2011-2015 ForgeRock AS.
016 */
017
018package org.forgerock.http.header;
019
020import static java.util.Collections.*;
021import static org.forgerock.http.header.HeaderUtil.*;
022
023import java.util.Collections;
024import java.util.List;
025
026import org.forgerock.http.protocol.Header;
027import org.forgerock.http.protocol.Message;
028
029/**
030 * Processes the <strong>{@code Content-Length}</strong> message header. For
031 * more information, see <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC
032 * 2616</a> §14.13.
033 */
034public class ContentLengthHeader extends Header {
035    /**
036     * Constructs a new header, initialized from the specified message.
037     *
038     * @param message
039     *            The message to initialize the header from.
040     * @return The parsed header.
041     */
042    public static ContentLengthHeader valueOf(final Message message) {
043        return valueOf(parseSingleValuedHeader(message, NAME));
044    }
045
046    /**
047     * Constructs a new header, initialized from the specified string value.
048     *
049     * @param string
050     *            The value to initialize the header from.
051     * @return The parsed header.
052     */
053    public static ContentLengthHeader valueOf(final String string) {
054        long length = -1;
055        if (string != null) {
056            try {
057                length = Long.parseLong(string);
058                length = length >= 0 ? length : -1;
059            } catch (NumberFormatException nfe) {
060                // will remain default of -1 from clear() call above
061            }
062        }
063        return new ContentLengthHeader(length);
064    }
065
066    /** The name of this header. */
067    public static final String NAME = "Content-Length";
068
069    /** The content length, or {@code -1} if not specified. */
070    private long length;
071
072    /**
073     * Constructs a new empty header whose length is set to -1.
074     */
075    public ContentLengthHeader() {
076        this(-1);
077    }
078
079    /**
080     * Constructs a new header with the provided content length.
081     *
082     * @param length
083     *            The content length, or {@code -1} if no content length has
084     *            been set.
085     */
086    public ContentLengthHeader(long length) {
087        this.length = length;
088    }
089
090    /**
091     * Returns the content length, or {@code -1} if no content length has been
092     * set.
093     *
094     * @return The content length, or {@code -1} if no content length has been
095     *         set.
096     */
097    public long getLength() {
098        return length;
099    }
100
101    @Override
102    public String getName() {
103        return NAME;
104    }
105
106    @Override
107    public List<String> getValues() {
108        return length >= 0 ? singletonList(Long.toString(length)) : Collections.<String>emptyList();
109    }
110
111    static class Factory extends AbstractSingleValuedHeaderFactory<ContentLengthHeader> {
112
113        @Override
114        public ContentLengthHeader parse(String value) {
115            return valueOf(value);
116        }
117
118        @Override
119        public ContentLengthHeader parse(Object value) throws MalformedHeaderException {
120            if (value instanceof Number) {
121                return new ContentLengthHeader(((Number) value).longValue());
122            }
123            return super.parse(value);
124        }
125    }
126}