All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.frameworkset.http.HttpRange Maven / Gradle / Ivy

Go to download

bboss is a j2ee framework include aop/ioc,mvc,persistent,taglib,rpc,event ,bean-xml serializable and so on.http://www.bbossgroups.com

There is a newer version: 6.2.7
Show newest version
package org.frameworkset.http;

import com.frameworkset.util.StringUtil;
import org.frameworkset.util.Assert;
import org.frameworkset.util.ObjectUtils;

import java.util.*;

public abstract class HttpRange {
	private static final String BYTE_RANGE_PREFIX = "bytes=";

	/**
	 * Return the start of the range given the total length of a representation.
	 * 
	 * @param length
	 *            the length of the representation
	 * @return the start of this range for the representation
	 */
	public abstract long getRangeStart(long length);

	/**
	 * Return the end of the range (inclusive) given the total length of a
	 * representation.
	 * 
	 * @param length
	 *            the length of the representation
	 * @return the end of the range for the representation
	 */
	public abstract long getRangeEnd(long length);

	/**
	 * Create an {@code HttpRange} from the given position to the end.
	 * 
	 * @param firstBytePos
	 *            the first byte position
	 * @return a byte range that ranges from {@code firstPos} till the end
	 * @see Byte
	 *      Ranges
	 */
	public static HttpRange createByteRange(long firstBytePos) {
		return new ByteRange(firstBytePos, null);
	}

	/**
	 * Create a {@code HttpRange} from the given fist to last position.
	 * 
	 * @param firstBytePos
	 *            the first byte position
	 * @param lastBytePos
	 *            the last byte position
	 * @return a byte range that ranges from {@code firstPos} till
	 *         {@code lastPos}
	 * @see Byte
	 *      Ranges
	 */
	public static HttpRange createByteRange(long firstBytePos, long lastBytePos) {
		return new ByteRange(firstBytePos, lastBytePos);
	}

	/**
	 * Create an {@code HttpRange} that ranges over the last given number of
	 * bytes.
	 * 
	 * @param suffixLength
	 *            the number of bytes for the range
	 * @return a byte range that ranges over the last {@code suffixLength}
	 *         number of bytes
	 * @see Byte
	 *      Ranges
	 */
	public static HttpRange createSuffixRange(long suffixLength) {
		return new SuffixByteRange(suffixLength);
	}

	/**
	 * Parse the given, comma-separated string into a list of {@code HttpRange}
	 * objects.
	 * 

* This method can be used to parse an {@code Range} header. * * @param ranges * the string to parse * @return the list of ranges * @throws IllegalArgumentException * if the string cannot be parsed */ public static List parseRanges(String ranges) { if (!StringUtil.hasLength(ranges)) { return Collections.emptyList(); } if (!ranges.startsWith(BYTE_RANGE_PREFIX)) { throw new IllegalArgumentException("Range '" + ranges + "' does not start with 'bytes='"); } ranges = ranges.substring(BYTE_RANGE_PREFIX.length()); String[] tokens = ranges.split(",\\s*"); List result = new ArrayList(tokens.length); for (String token : tokens) { result.add(parseRange(token)); } return result; } private static HttpRange parseRange(String range) { Assert.hasLength(range, "Range String must not be empty"); int dashIdx = range.indexOf('-'); if (dashIdx > 0) { long firstPos = Long.parseLong(range.substring(0, dashIdx)); if (dashIdx < range.length() - 1) { Long lastPos = Long.parseLong(range.substring(dashIdx + 1, range.length())); return new ByteRange(firstPos, lastPos); } else { return new ByteRange(firstPos, null); } } else if (dashIdx == 0) { long suffixLength = Long.parseLong(range.substring(1)); return new SuffixByteRange(suffixLength); } else { throw new IllegalArgumentException("Range '" + range + "' does not contain \"-\""); } } /** * Return a string representation of the given list of {@code HttpRange} * objects. *

* This method can be used to for an {@code Range} header. * * @param ranges * the ranges to create a string of * @return the string representation */ public static String toString(Collection ranges) { Assert.notEmpty(ranges, "Ranges Collection must not be empty"); StringBuilder builder = new StringBuilder(BYTE_RANGE_PREFIX); for (Iterator iterator = ranges.iterator(); iterator.hasNext();) { HttpRange range = iterator.next(); builder.append(range); if (iterator.hasNext()) { builder.append(", "); } } return builder.toString(); } /** * Represents an HTTP/1.1 byte range, with a first and optional last * position. * * @see Byte * Ranges * @see HttpRange#createByteRange(long) * @see HttpRange#createByteRange(long, long) */ private static class ByteRange extends HttpRange { private final long firstPos; private final Long lastPos; public ByteRange(long firstPos, Long lastPos) { assertPositions(firstPos, lastPos); this.firstPos = firstPos; this.lastPos = lastPos; } private void assertPositions(long firstBytePos, Long lastBytePos) { if (firstBytePos < 0) { throw new IllegalArgumentException("Invalid first byte position: " + firstBytePos); } if (lastBytePos != null && lastBytePos < firstBytePos) { throw new IllegalArgumentException("firstBytePosition=" + firstBytePos + " should be less then or equal to lastBytePosition=" + lastBytePos); } } @Override public long getRangeStart(long length) { return this.firstPos; } @Override public long getRangeEnd(long length) { if (this.lastPos != null && this.lastPos < length) { return this.lastPos; } else { return length - 1; } } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof ByteRange)) { return false; } ByteRange otherRange = (ByteRange) other; return (this.firstPos == otherRange.firstPos && ObjectUtils.nullSafeEquals(this.lastPos, otherRange.lastPos)); } @Override public int hashCode() { return (ObjectUtils.nullSafeHashCode(this.firstPos) * 31 + ObjectUtils.nullSafeHashCode(this.lastPos)); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(this.firstPos); builder.append('-'); if (this.lastPos != null) { builder.append(this.lastPos); } return builder.toString(); } } /** * Represents an HTTP/1.1 suffix byte range, with a number of suffix bytes. * * @see Byte * Ranges * @see HttpRange#createSuffixRange(long) */ private static class SuffixByteRange extends HttpRange { private final long suffixLength; public SuffixByteRange(long suffixLength) { if (suffixLength < 0) { throw new IllegalArgumentException("Invalid suffix length: " + suffixLength); } this.suffixLength = suffixLength; } @Override public long getRangeStart(long length) { if (this.suffixLength < length) { return length - this.suffixLength; } else { return 0; } } @Override public long getRangeEnd(long length) { return length - 1; } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof SuffixByteRange)) { return false; } SuffixByteRange otherRange = (SuffixByteRange) other; return (this.suffixLength == otherRange.suffixLength); } @Override public int hashCode() { return ObjectUtils.hashCode(this.suffixLength); } @Override public String toString() { return "-" + this.suffixLength; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy