package org.infinispan.rest;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.infinispan.commons.marshall.AbstractExternalizer;
import org.infinispan.commons.util.Util;
import org.infinispan.container.versioning.EntryVersion;
import org.infinispan.metadata.Metadata;
import org.jboss.marshalling.util.IdentityIntMap;
/**
* Metadata for MIME data stored in REST servers.
*
* @author Galder ZamarreƱo
* @since 5.3
*/
public class MimeMetadata implements Metadata {
protected final String contentType;
public MimeMetadata(String contentType) {
this.contentType = Objects.requireNonNull(contentType);
}
@Override
public long lifespan() {
return -1;
}
@Override
public long maxIdle() {
return -1;
}
@Override
public EntryVersion version() {
return null;
}
@Override
public Builder builder() {
return new MimeMetadataBuilder().contentType(contentType);
}
public String contentType() {
return contentType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MimeMetadata that = (MimeMetadata) o;
return contentType.equals(that.contentType);
}
@Override
public int hashCode() {
return 41 + contentType.hashCode();
}
@Override
public String toString() {
return "MimeMetadata{" +
"contentType='" + contentType + '\'' +
'}';
}
private static final int Immortal = 0;
private static final int Expirable = 1;
private static final int LifespanExpirable = 2;
private static final int MaxIdleExpirable = 3;
private static final IdentityIntMap<Class> numbers = new IdentityIntMap<>(4);
static {
numbers.put(MimeMetadata.class, Immortal);
numbers.put(MimeExpirableMetadata.class, Expirable);
numbers.put(MimeLifespanExpirableMetadata.class, LifespanExpirable);
numbers.put(MimeMaxIdleExpirableMetadata.class, MaxIdleExpirable);
}
public static class Externalizer extends AbstractExternalizer<MimeMetadata> {
@Override
public MimeMetadata readObject(ObjectInput input) throws IOException, ClassNotFoundException {
String contentType = input.readUTF();
int number = input.readUnsignedByte();
switch (number) {
case Immortal:
return new MimeMetadata(contentType);
case Expirable:
long lifespan = input.readLong();
long maxIdle = input.readLong();
return new MimeExpirableMetadata(contentType, lifespan, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS);
case LifespanExpirable:
lifespan = input.readLong();
return new MimeLifespanExpirableMetadata(contentType, lifespan, TimeUnit.MILLISECONDS);
case MaxIdleExpirable:
maxIdle = input.readLong();
return new MimeMaxIdleExpirableMetadata(contentType, maxIdle, TimeUnit.MILLISECONDS);
default:
throw new IllegalArgumentException("Unsupported type: " + number);
}
}
@Override
public void writeObject(ObjectOutput output, MimeMetadata meta) throws IOException {
output.writeUTF(meta.contentType);
int number = numbers.get(meta.getClass(), -1);
output.write(number);
switch (number) {
case Immortal:
// no-op
break;
case Expirable:
output.writeLong(meta.lifespan());
output.writeLong(meta.maxIdle());
break;
case LifespanExpirable:
output.writeLong(meta.lifespan());
break;
case MaxIdleExpirable:
output.writeLong(meta.maxIdle());
break;
default:
throw new IllegalArgumentException("Unsupported type: " + number);
}
}
@Override
public Set<Class<? extends MimeMetadata>> getTypeClasses() {
return Util.asSet(MimeMetadata.class, MimeExpirableMetadata.class,
MimeLifespanExpirableMetadata.class, MimeMaxIdleExpirableMetadata.class);
}
}
}
class MimeExpirableMetadata extends MimeMetadata {
private final long lifespanTime;
private final TimeUnit lifespanUnit;
private final long maxIdleTime;
private final TimeUnit maxIdleUnit;
public MimeExpirableMetadata(String contentType, long lifespanTime, TimeUnit lifespanUnit, long maxIdleTime,
TimeUnit maxIdleUnit) {
super(contentType);
this.lifespanTime = lifespanTime;
this.lifespanUnit = Objects.requireNonNull(lifespanUnit);
this.maxIdleTime = maxIdleTime;
this.maxIdleUnit = Objects.requireNonNull(maxIdleUnit);
}
@Override
public long lifespan() {
return lifespanUnit.toMillis(lifespanTime);
}
@Override
public long maxIdle() {
return maxIdleUnit.toMillis(maxIdleTime);
}
@Override
public Builder builder() {
return new MimeMetadataBuilder().contentType(contentType).lifespan(lifespanTime, lifespanUnit).maxIdle(maxIdleTime, maxIdleUnit);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
MimeExpirableMetadata that = (MimeExpirableMetadata) o;
if (lifespanTime != that.lifespanTime) return false;
if (maxIdleTime != that.maxIdleTime) return false;
if (lifespanUnit != that.lifespanUnit) return false;
return maxIdleUnit == that.maxIdleUnit;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (int) (lifespanTime ^ (lifespanTime >>> 32));
result = 31 * result + lifespanUnit.hashCode();
result = 31 * result + (int) (maxIdleTime ^ (maxIdleTime >>> 32));
result = 31 * result + maxIdleUnit.hashCode();
return result;
}
@Override
public String toString() {
return "MimeExpirableMetadata{" +
"lifespanTime=" + lifespanTime +
", lifespanUnit=" + lifespanUnit +
", maxIdleTime=" + maxIdleTime +
", maxIdleUnit=" + maxIdleUnit +
'}';
}
}
class MimeLifespanExpirableMetadata extends MimeMetadata {
private final long lifespanTime;
private final TimeUnit lifespanUnit;
MimeLifespanExpirableMetadata(String contentType, long lifespanTime, TimeUnit lifespanUnit) {
super(contentType);
this.lifespanTime = lifespanTime;
this.lifespanUnit = Objects.requireNonNull(lifespanUnit);
}
@Override
public long lifespan() {
return lifespanUnit.toMillis(lifespanTime);
}
@Override
public Builder builder() {
return new MimeMetadataBuilder().contentType(contentType).lifespan(lifespanTime, lifespanUnit);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
MimeLifespanExpirableMetadata that = (MimeLifespanExpirableMetadata) o;
if (lifespanTime != that.lifespanTime) return false;
return lifespanUnit == that.lifespanUnit;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (int) (lifespanTime ^ (lifespanTime >>> 32));
result = 31 * result + lifespanUnit.hashCode();
return result;
}
@Override
public String toString() {
return "MimeLifespanExpirableMetadata{" +
"lifespanTime=" + lifespanTime +
", lifespanUnit=" + lifespanUnit +
'}';
}
}
class MimeMaxIdleExpirableMetadata extends MimeMetadata {
private final long maxIdleTime;
private final TimeUnit maxIdleUnit;
public MimeMaxIdleExpirableMetadata(String contentType, long maxIdleTime, TimeUnit maxIdleUnit) {
super(contentType);
this.maxIdleTime = maxIdleTime;
this.maxIdleUnit = Objects.requireNonNull(maxIdleUnit);
}
@Override
public long maxIdle() {
return maxIdleUnit.toMillis(maxIdleTime);
}
@Override
public Builder builder() {
return new MimeMetadataBuilder().contentType(contentType).maxIdle(maxIdleTime, maxIdleUnit);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
MimeMaxIdleExpirableMetadata that = (MimeMaxIdleExpirableMetadata) o;
if (maxIdleTime != that.maxIdleTime) return false;
return maxIdleUnit == that.maxIdleUnit;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (int) (maxIdleTime ^ (maxIdleTime >>> 32));
result = 31 * result + maxIdleUnit.hashCode();
return result;
}
@Override
public String toString() {
return "MimeMaxIdleExpirableMetadata{" +
"maxIdleTime=" + maxIdleTime +
", maxIdleUnit=" + maxIdleUnit +
'}';
}
}