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 }