001package org.apache.commons.jcs3.auxiliary.remote; 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 022import java.io.IOException; 023import java.rmi.RemoteException; 024import java.rmi.server.UnicastRemoteObject; 025import java.util.concurrent.atomic.AtomicBoolean; 026 027import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheAttributes; 028import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheConstants; 029import org.apache.commons.jcs3.engine.behavior.ICompositeCacheManager; 030import org.apache.commons.jcs3.engine.behavior.IElementSerializer; 031import org.apache.commons.jcs3.log.Log; 032import org.apache.commons.jcs3.log.LogManager; 033 034/** 035 * Registered with RemoteCache server. The server updates the local caches via this listener. Each 036 * server assigns a unique listener id for a listener. 037 * <p> 038 * One listener is used per remote cache server. The same listener is used for all the regions that 039 * talk to a particular server. 040 */ 041public class RemoteCacheListener<K, V> 042 extends AbstractRemoteCacheListener<K, V> 043 implements IRemoteCacheConstants 044{ 045 /** The logger */ 046 private static final Log log = LogManager.getLog( RemoteCacheListener.class ); 047 048 /** Has this client been shutdown. */ 049 private AtomicBoolean disposed; 050 051 /** 052 * Only need one since it does work for all regions, just reference by multiple region names. 053 * <p> 054 * The constructor exports this object, making it available to receive incoming calls. The 055 * callback port is anonymous unless a local port value was specified in the configuration. 056 * <p> 057 * @param irca cache configuration 058 * @param cacheMgr the cache hub 059 * @param elementSerializer a custom serializer 060 */ 061 public RemoteCacheListener( final IRemoteCacheAttributes irca, 062 final ICompositeCacheManager cacheMgr, 063 final IElementSerializer elementSerializer ) 064 { 065 super( irca, cacheMgr, elementSerializer ); 066 disposed = new AtomicBoolean(false); 067 068 // Export this remote object to make it available to receive incoming 069 // calls. 070 try 071 { 072 UnicastRemoteObject.exportObject( this, irca.getLocalPort() ); 073 } 074 catch ( final RemoteException ex ) 075 { 076 log.error( "Problem exporting object.", ex ); 077 throw new IllegalStateException( ex.getMessage() ); 078 } 079 } 080 081 /** 082 * Deregister itself. 083 * <p> 084 * @throws IOException 085 */ 086 @Override 087 public synchronized void dispose() 088 throws IOException 089 { 090 if (disposed.compareAndSet(false, true)) 091 { 092 log.info( "Unexporting listener." ); 093 try 094 { 095 UnicastRemoteObject.unexportObject( this, true ); 096 } 097 catch ( final RemoteException ex ) 098 { 099 log.error( "Problem unexporting the listener.", ex ); 100 throw new IllegalStateException( ex.getMessage() ); 101 } 102 } 103 } 104 105 /** 106 * For easier debugging. 107 * <p> 108 * @return Basic info on this listener. 109 */ 110 @Override 111 public String toString() 112 { 113 final StringBuilder buf = new StringBuilder(); 114 buf.append( "\n RemoteCacheListener: " ); 115 buf.append( super.toString() ); 116 return buf.toString(); 117 } 118}