1 19 20 package org.apache.cayenne.event; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.EventListener ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 29 import org.apache.cayenne.util.Util; 30 31 55 public abstract class EventBridge implements EventListener { 60 61 public static final int RECEIVE_LOCAL = 1; 62 public static final int RECEIVE_EXTERNAL = 2; 63 public static final int RECEIVE_LOCAL_EXTERNAL = 3; 64 65 protected String externalSubject; 66 protected Collection localSubjects; 67 protected EventManager eventManager; 68 protected int mode; 69 70 protected Object externalEventSource; 71 72 Collection listeners; 74 75 81 public static String convertToExternalSubject(EventSubject localSubject) { 82 char[] chars = localSubject.getSubjectName().toCharArray(); 83 for (int i = 0; i < chars.length; i++) { 84 if (chars[i] == '/' || chars[i] == '.') { 85 chars[i] = '_'; 86 } 87 } 88 89 return new String (chars); 90 } 91 92 95 public EventBridge(EventSubject localSubject, String externalSubject) { 96 this(Collections.singleton(localSubject), externalSubject); 97 } 98 99 104 public EventBridge(Collection localSubjects, String externalSubject) { 105 this.localSubjects = new HashSet (localSubjects); 106 this.externalSubject = externalSubject; 107 } 108 109 112 public String getExternalSubject() { 113 return externalSubject; 114 } 115 116 121 public boolean isRunning() { 122 return eventManager != null; 123 } 124 125 130 public Collection getLocalSubjects() { 131 return localSubjects; 132 } 133 134 140 public EventManager getEventManager() { 141 return eventManager; 142 } 143 144 151 public Object getExternalEventSource() { 152 return externalEventSource != null ? externalEventSource : this; 153 } 154 155 159 public boolean receivesLocalEvents() { 160 return mode == RECEIVE_LOCAL_EXTERNAL || mode == RECEIVE_LOCAL; 161 } 162 163 166 public boolean receivesExternalEvents() { 167 return mode == RECEIVE_LOCAL_EXTERNAL || mode == RECEIVE_EXTERNAL; 168 } 169 170 179 public void startup(EventManager eventManager, int mode) throws Exception { 180 this.startup(eventManager, mode, null); 181 } 182 183 193 public void startup(EventManager eventManager, int mode, Object localEventSource) 194 throws Exception { 195 startup(eventManager, mode, localEventSource, null); 196 } 197 198 211 public void startup( 212 EventManager eventManager, 213 int mode, 214 Object localEventSource, 215 Object remoteEventSource) throws Exception { 216 217 if (eventManager == null) { 218 throw new IllegalArgumentException ("'eventManager' can't be null."); 219 } 220 221 if (this.eventManager != null) { 223 shutdown(); 224 } 225 226 this.externalEventSource = remoteEventSource; 227 this.eventManager = eventManager; 228 this.mode = mode; 229 230 if (receivesLocalEvents() && !localSubjects.isEmpty()) { 231 232 listeners = new ArrayList (localSubjects.size()); 233 234 Iterator it = localSubjects.iterator(); 235 while (it.hasNext()) { 236 237 EventSubject subject = (EventSubject) it.next(); 238 SubjectListener listener = new SubjectListener(subject); 239 240 listeners.add(listener); 241 eventManager.addNonBlockingListener( 242 listener, 243 "onLocalEvent", 244 CayenneEvent.class, 245 subject, 246 localEventSource); 247 } 248 } 249 250 startupExternal(); 251 } 252 253 256 protected abstract void startupExternal() throws Exception ; 257 258 261 public void shutdown() throws Exception { 262 263 this.externalEventSource = null; 264 265 if (listeners != null && eventManager != null) { 266 267 Iterator it = listeners.iterator(); 268 while (it.hasNext()) { 269 SubjectListener listener = (SubjectListener) it.next(); 270 eventManager.removeListener(listener, listener.subject); 271 } 272 273 eventManager = null; 274 listeners = null; 275 } 276 277 shutdownExternal(); 278 } 279 280 284 protected abstract void shutdownExternal() throws Exception ; 285 286 291 protected void onExternalEvent(CayenneEvent event) { 292 if (eventManager != null) { 293 294 EventSubject localSubject = event.getSubject(); 295 296 if (localSubject == null || !localSubjects.contains(localSubject)) { 298 return; 299 } 300 301 event.setSource(getExternalEventSource()); 302 event.setPostedBy(this); 303 304 eventManager.postEvent(event, localSubject); 307 } 308 else { 309 throw new IllegalStateException ( 310 "Can't post events. EventBridge was not started properly. " 311 + "EventManager is null."); 312 } 313 } 314 315 318 protected abstract void sendExternalEvent(CayenneEvent localEvent) throws Exception ; 319 320 final class SubjectListener { 321 322 EventSubject subject; 323 324 SubjectListener(EventSubject subject) { 325 this.subject = subject; 326 } 327 328 void onLocalEvent(CayenneEvent event) throws Exception { 329 330 if (event.getSource() != getExternalEventSource() 332 && event.getPostedBy() != EventBridge.this) { 333 334 if (!subject.equals(event.getSubject())) { 337 CayenneEvent clone = (CayenneEvent) Util.cloneViaSerialization(event); 338 clone.setSubject(subject); 339 clone.setPostedBy(event.getPostedBy()); 340 clone.setSource(event.getSource()); 341 342 event = clone; 343 } 344 345 sendExternalEvent(event); 346 } 347 } 348 } 349 } 350 | Popular Tags |