001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.space; 020 021import org.jpos.core.Configuration; 022import org.jpos.core.ConfigurationException; 023import org.jpos.core.Configurable; 024 025import javax.naming.InitialContext; 026import javax.naming.NamingException; 027import java.io.Serializable; 028import java.rmi.RemoteException; 029import java.rmi.registry.LocateRegistry; 030import java.rmi.registry.Registry; 031import java.rmi.server.*; 032import java.util.Set; 033 034/** 035 * RMI Space Proxy 036 * @author Alejandro Revilla 037 * @author Niclas Hedhman 038 * @version $Revision$ $Date$ 039 * @since 1.4.9 040 */ 041@SuppressWarnings("unchecked") 042public class SpaceProxy implements RemoteSpace, Configurable { 043 Space sp; 044 Configuration cfg; 045 private RemoteRef ref; 046 private RemoteStub stub; 047 /** 048 * Constructs a proxy backed by the default jPOS space. 049 * 050 * @throws RemoteException if RMI export fails 051 */ 052 public SpaceProxy () throws RemoteException { 053 super(); 054 sp = SpaceFactory.getSpace (); 055 startService (); 056 } 057 /** 058 * Constructs a proxy backed by the space resolved from {@code spaceUri}. 059 * 060 * @param spaceUri SpaceFactory-style space URI 061 * @throws RemoteException if RMI export fails 062 */ 063 public SpaceProxy (String spaceUri) throws RemoteException { 064 super (); 065 sp = SpaceFactory.getSpace (spaceUri); 066 startService (); 067 } 068 069 private void startService () throws RemoteException 070 { 071 try { 072 LocateRegistry.createRegistry (Registry.REGISTRY_PORT); 073 } catch (ExportException ignored) { 074 // NOPMD: ok to happen 075 } 076 stub = UnicastRemoteObject.exportObject (this); 077 ref = stub.getRef(); 078 } 079 080 public void out (Serializable key, Serializable value) 081 throws RemoteException 082 { 083 sp.out (key, value); 084 } 085 public void out (Serializable key, Serializable value, long timeout) 086 throws RemoteException 087 { 088 sp.out (key, value, timeout); 089 } 090 public Serializable in (Serializable key) 091 throws RemoteException 092 { 093 return (Serializable) sp.in (key); 094 } 095 public Serializable rd (Serializable key) 096 throws RemoteException 097 { 098 return (Serializable) sp.rd (key); 099 } 100 public Serializable in (Serializable key, long timeout) 101 throws RemoteException 102 { 103 return (Serializable) sp.in (key, timeout); 104 } 105 public Serializable rd (Serializable key, long timeout) 106 throws RemoteException 107 { 108 return (Serializable) sp.rd (key, timeout); 109 } 110 public Serializable inp (Serializable key) 111 throws RemoteException 112 { 113 return (Serializable) sp.inp (key); 114 } 115 public Serializable rdp (Serializable key) 116 throws RemoteException 117 { 118 return (Serializable) sp.rdp (key); 119 } 120 /** Unexports this proxy from the RMI runtime, retrying once after a brief delay. */ 121 public void shutdown() { 122 try { 123 if (UnicastRemoteObject.unexportObject (this, false)) 124 return; 125 Thread.sleep (5000); 126 UnicastRemoteObject.unexportObject (this, true); 127 } catch (Exception ignored) { 128 // NOPMD: nothing to do .. we're shutting down ... 129 } 130 } 131 public void setConfiguration (Configuration cfg) 132 throws ConfigurationException 133 { 134 this.cfg = cfg; 135 try { 136 InitialContext ctx = new InitialContext (); 137 ctx.rebind (cfg.get ("name"), stub); 138 } catch (NamingException e) { 139 throw new ConfigurationException (e); 140 } 141 } 142 /** 143 * Returns the underlying local-space key set when available. 144 * 145 * @return the live key set, or {@code null} when the proxied space is not local 146 */ 147 public Set getKeySet () { 148 if (sp instanceof LocalSpace) 149 return ((LocalSpace)sp).getKeySet (); 150 else 151 return null; 152 } 153 public String toString() { 154 if (ref == null) 155 return getClass().getName() + "[<unexported>]"; 156 else 157 return getClass().getName() + "[" + ref.remoteToString() + "]"; 158 } 159 public int hashCode() { 160 if (ref == null ) 161 return super.hashCode(); 162 else 163 return ref.remoteHashCode(); 164 } 165 public boolean equals (Object obj) { 166 if (obj instanceof RemoteObject) { 167 if (ref == null) { 168 return obj == this; 169 } else { 170 RemoteRef otherRef = ((RemoteObject)obj).getRef(); 171 return ref.remoteEquals (otherRef); 172 } 173 } else if (obj != null) { 174 return obj.equals (this); 175 } else { 176 return false; 177 } 178 } 179} 180