View Javadoc

1   package org.apache.jcs.auxiliary.lateral;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.Serializable;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.List;
27  import java.util.Set;
28  import java.util.HashSet;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.jcs.auxiliary.AuxiliaryCache;
33  import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
34  import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheAttributes;
35  import org.apache.jcs.engine.behavior.ICacheElement;
36  import org.apache.jcs.engine.behavior.ICacheType;
37  import org.apache.jcs.engine.stats.StatElement;
38  import org.apache.jcs.engine.stats.Stats;
39  import org.apache.jcs.engine.stats.behavior.IStatElement;
40  import org.apache.jcs.engine.stats.behavior.IStats;
41  
42  /***
43   * Used to provide access to multiple services under nowait protection.
44   * Composite factory should construct LateralCacheNoWaitFacade to give to the
45   * composite cache out of caches it constructs from the varies manager to
46   * lateral services. Perhaps the lateralcache factory should be able to do this.
47   *
48   */
49  public class LateralCacheNoWaitFacade
50      implements AuxiliaryCache
51  {
52      private static final long serialVersionUID = -9047687810358008955L;
53  
54      private final static Log log = LogFactory.getLog( LateralCacheNoWaitFacade.class );
55  
56      /*** The queuing facade to the client. */
57      public LateralCacheNoWait[] noWaits;
58  
59      private String cacheName;
60  
61      private ILateralCacheAttributes lateralCacheAttributes;
62  
63      /***
64       * Constructs with the given lateral cache, and fires events to any
65       * listeners.
66       *
67       * @param noWaits
68       * @param cattr
69       */
70      public LateralCacheNoWaitFacade( LateralCacheNoWait[] noWaits, ILateralCacheAttributes cattr )
71      {
72          if ( log.isDebugEnabled() )
73          {
74              log.debug( "CONSTRUCTING NO WAIT FACADE" );
75          }
76          this.noWaits = noWaits;
77          this.cacheName = cattr.getCacheName();
78          this.lateralCacheAttributes = cattr;
79      }
80  
81      /***
82       * Adds a no wait to the list if it isn't already in the list.
83       * <p>
84       * @param noWait
85       * @return true if it wasn't alreay contained
86       */
87      public boolean addNoWait( LateralCacheNoWait noWait )
88      {
89          if ( noWait == null )
90          {
91              return false;
92          }
93  
94          for ( int i = 0; i < noWaits.length; i++ )
95          {
96              // we know noWait isn't null
97              if ( noWait.equals( noWaits[i] ) )
98              {
99                  if ( log.isDebugEnabled() )
100                 {
101                     log.debug( "No Wait already contained, [" + noWait + "]" );
102                 }
103                 return false;
104             }
105         }
106 
107         LateralCacheNoWait[] newArray = new LateralCacheNoWait[noWaits.length + 1];
108 
109         System.arraycopy( noWaits, 0, newArray, 0, noWaits.length );
110 
111         // set the last position to the new noWait
112         newArray[noWaits.length] = noWait;
113 
114         noWaits = newArray;
115 
116         return true;
117 
118     }
119 
120     /*
121      * (non-Javadoc)
122      *
123      * @see org.apache.jcs.engine.behavior.ICache#update(org.apache.jcs.engine.behavior.ICacheElement)
124      */
125     public void update( ICacheElement ce )
126         throws IOException
127     {
128         if ( log.isDebugEnabled() )
129         {
130             log.debug( "updating through lateral cache facade, noWaits.length = " + noWaits.length );
131         }
132         try
133         {
134             for ( int i = 0; i < noWaits.length; i++ )
135             {
136                 noWaits[i].update( ce );
137             }
138         }
139         catch ( Exception ex )
140         {
141             log.error( ex );
142         }
143     }
144 
145     /***
146      * Synchronously reads from the lateral cache.
147      * <p>
148      * @param key
149      * @return ICacheElement
150      */
151     public ICacheElement get( Serializable key )
152     {
153         for ( int i = 0; i < noWaits.length; i++ )
154         {
155             try
156             {
157                 Object obj = noWaits[i].get( key );
158 
159                 if ( obj != null )
160                 {
161                     // TODO: return after first success
162                     // could do this simultaneously
163                     // serious blocking risk here
164                     return (ICacheElement) obj;
165                 }
166             }
167             catch ( Exception ex )
168             {
169                 log.error( "Failed to get", ex );
170             }
171             return null;
172         }
173         return null;
174     }
175 
176     /*
177      * (non-Javadoc)
178      *
179      * @see org.apache.jcs.auxiliary.AuxiliaryCache#getGroupKeys(java.lang.String)
180      */
181     public Set getGroupKeys( String group )
182     {
183         HashSet allKeys = new HashSet();
184         for ( int i = 0; i < noWaits.length; i++ )
185         {
186             AuxiliaryCache aux = noWaits[i];
187             if ( aux != null )
188             {
189                 try
190                 {
191                     allKeys.addAll( aux.getGroupKeys( group ) );
192                 }
193                 catch ( IOException e )
194                 {
195                     // ignore
196                 }
197             }
198         }
199         return allKeys;
200     }
201 
202     /***
203      * Adds a remove request to the lateral cache.
204      * <p>
205      * @param key
206      * @return always false.
207      */
208     public boolean remove( Serializable key )
209     {
210         try
211         {
212             for ( int i = 0; i < noWaits.length; i++ )
213             {
214                 noWaits[i].remove( key );
215             }
216         }
217         catch ( Exception ex )
218         {
219             log.error( ex );
220         }
221         return false;
222     }
223 
224     /***
225      * Adds a removeAll request to the lateral cache.
226      */
227     public void removeAll()
228     {
229         try
230         {
231             for ( int i = 0; i < noWaits.length; i++ )
232             {
233                 noWaits[i].removeAll();
234             }
235         }
236         catch ( Exception ex )
237         {
238             log.error( ex );
239         }
240     }
241 
242     /*** Adds a dispose request to the lateral cache. */
243     public void dispose()
244     {
245         try
246         {
247             for ( int i = 0; i < noWaits.length; i++ )
248             {
249                 noWaits[i].dispose();
250             }
251         }
252         catch ( Exception ex )
253         {
254             log.error( ex );
255         }
256     }
257 
258     /***
259      * No lateral invokation.
260      *
261      * @return The size value
262      */
263     public int getSize()
264     {
265         return 0;
266         //cache.getSize();
267     }
268 
269     /***
270      * Gets the cacheType attribute of the LateralCacheNoWaitFacade object
271      *
272      * @return The cacheType value
273      */
274     public int getCacheType()
275     {
276         return ICacheType.LATERAL_CACHE;
277     }
278 
279     /***
280      * Gets the cacheName attribute of the LateralCacheNoWaitFacade object
281      *
282      * @return The cacheName value
283      */
284     public String getCacheName()
285     {
286         return "";
287         //cache.getCacheName();
288     }
289 
290     // need to do something with this
291     /***
292      * Gets the status attribute of the LateralCacheNoWaitFacade object
293      *
294      * @return The status value
295      */
296     public int getStatus()
297     {
298         return 0;
299         //q.isAlive() ? cache.getStatus() : cache.STATUS_ERROR;
300     }
301 
302     /***
303      * @return Returns the AuxiliaryCacheAttributes.
304      */
305     public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
306     {
307         return this.lateralCacheAttributes;
308     }
309 
310     /*
311      * (non-Javadoc)
312      *
313      * @see java.lang.Object#toString()
314      */
315     public String toString()
316     {
317         return "LateralCacheNoWaitFacade: " + cacheName;
318     }
319 
320     /***
321      * getStats
322      *
323      * @return String
324      */
325     public String getStats()
326     {
327         return getStatistics().toString();
328     }
329 
330     /*
331      * (non-Javadoc)
332      *
333      * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
334      */
335     public IStats getStatistics()
336     {
337         IStats stats = new Stats();
338         stats.setTypeName( "Lateral Cache No Wait Facade" );
339 
340         ArrayList elems = new ArrayList();
341 
342         IStatElement se = null;
343 
344         if ( noWaits != null )
345         {
346             se = new StatElement();
347             se.setName( "Number of No Waits" );
348             se.setData( "" + noWaits.length );
349             elems.add( se );
350 
351             for ( int i = 0; i < noWaits.length; i++ )
352             {
353                 if ( noWaits[i] != null )
354                 {
355                     // get the stats from the super too
356                     // get as array, convert to list, add list to our outer list
357                     IStats sStats = noWaits[i].getStatistics();
358                     IStatElement[] sSEs = sStats.getStatElements();
359                     List sL = Arrays.asList( sSEs );
360                     elems.addAll( sL );
361                 }
362             }
363 
364         }
365 
366         // get an array and put them in the Stats object
367         IStatElement[] ses = (IStatElement[]) elems.toArray( new StatElement[0] );
368         stats.setStatElements( ses );
369 
370         return stats;
371     }
372 }