1 /** 2 * Copyright 2003-2006 Greg Luck 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package net.sf.ehcache.distribution; 18 19 import net.sf.ehcache.Cache; 20 import net.sf.ehcache.Element; 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 24 import java.io.IOException; 25 import java.io.Serializable; 26 import java.rmi.Remote; 27 import java.rmi.RemoteException; 28 import java.rmi.server.RMISocketFactory; 29 import java.rmi.server.UnicastRemoteObject; 30 import java.util.List; 31 32 /** 33 * An RMI based implementation of <code>CachePeer</code>. 34 * <p/> 35 * This class features a customised RMIClientSocketFactory which enables socket timeouts to be configured. 36 * 37 * @author Greg Luck 38 * @version $Id: RMICachePeer.java 52 2006-04-24 14:50:03Z gregluck $ 39 * @noinspection FieldCanBeLocal 40 */ 41 public class RMICachePeer extends UnicastRemoteObject implements CachePeer, Remote { 42 43 private static final Log LOG = LogFactory.getLog(RMICachePeer.class.getName()); 44 45 private final String hostname; 46 private final Integer port; 47 private final Cache cache; 48 49 /** 50 * Construct a new remote peer. 51 * 52 * @param cache 53 * @param hostName 54 * @param port 55 * @param socketTimeoutMillis 56 * @throws RemoteException 57 */ 58 public RMICachePeer(Cache cache, String hostName, Integer port, Integer socketTimeoutMillis) 59 throws RemoteException { 60 super(0, new ConfigurableRMIClientSocketFactory(socketTimeoutMillis), 61 RMISocketFactory.getDefaultSocketFactory()); 62 63 this.hostname = hostName; 64 this.port = port; 65 this.cache = cache; 66 } 67 68 /** 69 * {@inheritDoc} 70 * <p/> 71 * This implementation gives an URL which has meaning to the RMI remoting system. 72 * 73 * @return the URL, without the scheme, as a string e.g. //hostname:port/cacheName 74 */ 75 public final String getUrl() { 76 return new StringBuffer() 77 .append("//") 78 .append(hostname) 79 .append(":") 80 .append(port) 81 .append("/") 82 .append(cache.getName()) 83 .toString(); 84 } 85 86 /** 87 * {@inheritDoc} 88 * <p/> 89 * This implementation gives an URL which has meaning to the RMI remoting system. 90 * 91 * @return the URL, without the scheme, as a string e.g. //hostname:port 92 */ 93 public final String getUrlBase() { 94 return new StringBuffer() 95 .append("//") 96 .append(hostname) 97 .append(":") 98 .append(port) 99 .toString(); 100 } 101 102 103 /** 104 * Puts an Element into the underlying cache without notifying listeners or updating statistics. 105 * 106 * @param element 107 * @throws java.rmi.RemoteException 108 * @throws IllegalArgumentException 109 * @throws IllegalStateException 110 */ 111 public void put(Element element) throws RemoteException, IllegalArgumentException, IllegalStateException { 112 cache.put(element, true); 113 } 114 115 116 /** 117 * Removes an Element from the underlying cache without notifying listeners or updating statistics. 118 * 119 * @param key 120 * @return true if the element was removed, false if it was not found in the cache 121 * @throws RemoteException 122 * @throws IllegalStateException 123 */ 124 public final boolean remove(Serializable key) throws RemoteException, IllegalStateException { 125 return cache.remove(key, true); 126 } 127 128 /** 129 * Removes all cached items. 130 * 131 * @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE} 132 */ 133 public final void removeAll() throws RemoteException, IllegalStateException { 134 try { 135 cache.removeAll(); 136 } catch (IOException e) { 137 LOG.error(e.getMessage()); 138 throw new RemoteException(e.getMessage()); 139 } 140 } 141 142 /** 143 * Send the cache peer with an ordered list of {@link EventMessage}s 144 * <p/> 145 * This enables multiple messages to be delivered in one network invocation. 146 */ 147 public final void send(List eventMessages) throws RemoteException { 148 for (int i = 0; i < eventMessages.size(); i++) { 149 EventMessage eventMessage = (EventMessage) eventMessages.get(i); 150 if (eventMessage.getEvent() == EventMessage.PUT) { 151 put(eventMessage.getElement()); 152 } else { 153 remove(eventMessage.getSerializableKey()); 154 } 155 } 156 } 157 158 /** 159 * Gets the cache name 160 */ 161 public final String getName() throws RemoteException { 162 return cache.getName(); 163 } 164 165 166 /** 167 * {@inheritDoc} 168 */ 169 public final String getGuid() throws RemoteException { 170 return cache.getGuid(); 171 } 172 173 /** 174 * Gets the cache instance that this listener is bound to 175 */ 176 final Cache getBoundCacheInstance() { 177 return cache; 178 } 179 180 }