// ======================================================================== // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.io; import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; import org.eclipse.jetty.util.StringMap; /* ------------------------------------------------------------------------------- */ /** * Stores a collection of {@link Buffer} objects. * Buffers are stored in an ordered collection and can retreived by index or value * */ public class BufferCache { private final HashMap _bufferMap=new HashMap(); private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE); private final ArrayList _index= new ArrayList(); /* ------------------------------------------------------------------------------- */ /** Add a buffer to the cache at the specified index. * @param value The content of the buffer. */ public CachedBuffer add(String value, int ordinal) { CachedBuffer buffer= new CachedBuffer(value, ordinal); _bufferMap.put(buffer, buffer); _stringMap.put(value, buffer); while ((ordinal - _index.size()) >= 0) _index.add(null); if (_index.get(ordinal)==null) _index.add(ordinal, buffer); return buffer; } public CachedBuffer get(int ordinal) { if (ordinal < 0 || ordinal >= _index.size()) return null; return (CachedBuffer)_index.get(ordinal); } public CachedBuffer get(Buffer buffer) { return (CachedBuffer)_bufferMap.get(buffer); } public CachedBuffer get(String value) { return (CachedBuffer)_stringMap.get(value); } public Buffer lookup(Buffer buffer) { if (buffer instanceof CachedBuffer) return buffer; Buffer b= get(buffer); if (b == null) { if (buffer instanceof Buffer.CaseInsensitve) return buffer; return new ByteArrayBuffer.CaseInsensitive(buffer.asArray(),0,buffer.length(),Buffer.IMMUTABLE); } return b; } public CachedBuffer getBest(byte[] value, int offset, int maxLength) { Entry entry = _stringMap.getBestEntry(value, offset, maxLength); if (entry!=null) return (CachedBuffer)entry.getValue(); return null; } public Buffer lookup(String value) { Buffer b= get(value); if (b == null) { return new CachedBuffer(value,-1); } return b; } public String toString(Buffer buffer) { return lookup(buffer).toString(); } public int getOrdinal(String value) { CachedBuffer buffer = (CachedBuffer)_stringMap.get(value); return buffer==null?-1:buffer.getOrdinal(); } public int getOrdinal(Buffer buffer) { if (buffer instanceof CachedBuffer) return ((CachedBuffer)buffer).getOrdinal(); buffer=lookup(buffer); if (buffer!=null && buffer instanceof CachedBuffer) return ((CachedBuffer)buffer).getOrdinal(); return -1; } public static class CachedBuffer extends ByteArrayBuffer.CaseInsensitive { private final int _ordinal; private HashMap _associateMap=null; public CachedBuffer(String value, int ordinal) { super(value); _ordinal= ordinal; } public int getOrdinal() { return _ordinal; } public CachedBuffer getAssociate(Object key) { if (_associateMap==null) return null; return (CachedBuffer)_associateMap.get(key); } // TODO Replace Associate with a mime encoding specific solution public void setAssociate(Object key, CachedBuffer associate) { if (_associateMap==null) _associateMap=new HashMap(); _associateMap.put(key,associate); } } @Override public String toString() { return "CACHE["+ "bufferMap="+_bufferMap+ ",stringMap="+_stringMap+ ",index="+_index+ "]"; } }