View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.io;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.Map.Entry;
24  
25  import org.eclipse.jetty.util.StringMap;
26  
27  /* ------------------------------------------------------------------------------- */
28  /** 
29   * Stores a collection of {@link Buffer} objects.
30   * Buffers are stored in an ordered collection and can retreived by index or value
31   * 
32   */
33  public class BufferCache
34  {
35      private final HashMap _bufferMap=new HashMap();
36      private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE);
37      private final ArrayList _index= new ArrayList();
38  
39      /* ------------------------------------------------------------------------------- */
40      /** Add a buffer to the cache at the specified index.
41       * @param value The content of the buffer.
42       */
43      public CachedBuffer add(String value, int ordinal)
44      {
45          CachedBuffer buffer= new CachedBuffer(value, ordinal);
46          _bufferMap.put(buffer, buffer);
47          _stringMap.put(value, buffer);
48          while ((ordinal - _index.size()) >= 0)
49              _index.add(null);
50          if (_index.get(ordinal)==null)
51              _index.add(ordinal, buffer);
52          return buffer;
53      }
54  
55      public CachedBuffer get(int ordinal)
56      {
57          if (ordinal < 0 || ordinal >= _index.size())
58              return null;
59          return (CachedBuffer)_index.get(ordinal);
60      }
61  
62      public CachedBuffer get(Buffer buffer)
63      {
64          return (CachedBuffer)_bufferMap.get(buffer);
65      }
66  
67      public CachedBuffer get(String value)
68      {
69          return (CachedBuffer)_stringMap.get(value);
70      }
71  
72      public Buffer lookup(Buffer buffer)
73      {
74          if (buffer instanceof CachedBuffer)
75              return buffer;
76          
77          Buffer b= get(buffer);
78          if (b == null)
79          {
80              if (buffer instanceof Buffer.CaseInsensitve)
81                  return buffer;
82              return new ByteArrayBuffer.CaseInsensitive(buffer.asArray(),0,buffer.length(),Buffer.IMMUTABLE);
83          }
84  
85          return b;
86      }
87      
88      public CachedBuffer getBest(byte[] value, int offset, int maxLength)
89      {
90          Entry entry = _stringMap.getBestEntry(value, offset, maxLength);
91          if (entry!=null)
92              return (CachedBuffer)entry.getValue();
93          return null;
94      }
95  
96      public Buffer lookup(String value)
97      {
98          Buffer b= get(value);
99          if (b == null)
100         {
101             return new CachedBuffer(value,-1);
102         }
103         return b;
104     }
105 
106     public String toString(Buffer buffer)
107     {
108         return lookup(buffer).toString();
109     }
110 
111     public int getOrdinal(String value)
112     {
113         CachedBuffer buffer = (CachedBuffer)_stringMap.get(value);
114         return buffer==null?-1:buffer.getOrdinal();
115     }
116     
117     public int getOrdinal(Buffer buffer)
118     {
119         if (buffer instanceof CachedBuffer)
120             return ((CachedBuffer)buffer).getOrdinal();
121         buffer=lookup(buffer);
122         if (buffer!=null && buffer instanceof CachedBuffer)
123             return ((CachedBuffer)buffer).getOrdinal();
124         return -1;
125     }
126     
127     public static class CachedBuffer extends ByteArrayBuffer.CaseInsensitive
128     {
129         private final int _ordinal;
130         private HashMap _associateMap=null;
131         
132         public CachedBuffer(String value, int ordinal)
133         {
134             super(value);
135             _ordinal= ordinal;
136         }
137 
138         public int getOrdinal()
139         {
140             return _ordinal;
141         }
142 
143         public CachedBuffer getAssociate(Object key)
144         {
145             if (_associateMap==null)
146                 return null;
147             return (CachedBuffer)_associateMap.get(key);
148         }
149 
150         // TODO Replace Associate with a mime encoding specific solution
151         public void setAssociate(Object key, CachedBuffer associate)
152         {
153             if (_associateMap==null)
154                 _associateMap=new HashMap();
155             _associateMap.put(key,associate);
156         }
157     }
158     
159     
160     @Override
161     public String toString()
162     {
163         return "CACHE["+
164         	"bufferMap="+_bufferMap+
165         	",stringMap="+_stringMap+
166         	",index="+_index+
167         	"]";
168     }
169 }