001    package org.apache.jcs.auxiliary.remote.http.client;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.Serializable;
023    import java.util.ArrayList;
024    import java.util.HashMap;
025    
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    import org.apache.jcs.auxiliary.AuxiliaryCache;
029    import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
030    import org.apache.jcs.auxiliary.AuxiliaryCacheFactory;
031    import org.apache.jcs.auxiliary.remote.RemoteCacheNoWait;
032    import org.apache.jcs.auxiliary.remote.RemoteCacheNoWaitFacade;
033    import org.apache.jcs.auxiliary.remote.server.behavior.RemoteType;
034    import org.apache.jcs.engine.behavior.ICache;
035    import org.apache.jcs.engine.behavior.ICompositeCacheManager;
036    import org.apache.jcs.engine.behavior.IElementSerializer;
037    import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
038    
039    /**
040     * The RemoteCacheFactory creates remote caches for the cache hub. It returns a no wait facade which
041     * is a wrapper around a no wait. The no wait object is either an active connection to a remote
042     * cache or a balking zombie if the remote cache is not accessible. It should be transparent to the
043     * clients.
044     */
045    public class RemoteHttpCacheFactory
046        implements AuxiliaryCacheFactory
047    {
048        /** The logger. */
049        private final static Log log = LogFactory.getLog( RemoteHttpCacheFactory.class );
050    
051        /** The name of this auxiliary */
052        private String name;
053    
054        /** store reference of facades to initiate failover */
055        private final static HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>> facades =
056            new HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>>();
057    
058        /**
059         * For LOCAL clients we get a handle to all the failovers, but we do not register a listener
060         * with them. We create the RemoteCacheManager, but we do not get a cache.
061         * <p>
062         * The failover runner will get a cache from the manager. When the primary is restored it will
063         * tell the manager for the failover to deregister the listener.
064         * <p>
065         * @param iaca
066         * @param cacheMgr
067         * @param cacheEventLogger
068         * @param elementSerializer
069         * @return AuxiliaryCache
070         */
071        public <K extends Serializable, V extends Serializable> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
072                                           ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
073        {
074            RemoteHttpCacheAttributes rca = (RemoteHttpCacheAttributes) iaca;
075    
076            ArrayList<ICache<K, V>> noWaits = new ArrayList<ICache<K, V>>();
077    
078            RemoteHttpCacheManager rcm = RemoteHttpCacheManager.getInstance( cacheMgr, cacheEventLogger, elementSerializer );
079            // TODO, use the configured value.
080            rca.setRemoteType( RemoteType.LOCAL );
081            ICache<K, V> ic = rcm.getCache( rca );
082            if ( ic != null )
083            {
084                noWaits.add( ic );
085            }
086            else
087            {
088                log.info( "noWait is null" );
089            }
090    
091            @SuppressWarnings("unchecked") // No generic arrays in java
092            RemoteCacheNoWait<K, V>[] rcnwArray = noWaits.toArray( new RemoteCacheNoWait[0] );
093            RemoteCacheNoWaitFacade<K, V> rcnwf =
094                new RemoteCacheNoWaitFacade<K, V>(rcnwArray, rca, cacheMgr, cacheEventLogger, elementSerializer );
095    
096            getFacades().put( rca.getCacheName(), rcnwf );
097    
098            return rcnwf;
099        }
100    
101        /**
102         * Gets the name attribute of the RemoteCacheFactory object
103         * <p>
104         * @return The name value
105         */
106        public String getName()
107        {
108            return this.name;
109        }
110    
111        /**
112         * Sets the name attribute of the RemoteCacheFactory object
113         * <p>
114         * @param name The new name value
115         */
116        public void setName( String name )
117        {
118            this.name = name;
119        }
120    
121        /**
122         * The facades are what the cache hub talks to.
123         * @return Returns the facades.
124         */
125        public static HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>> getFacades()
126        {
127            return facades;
128        }
129    }