+ " and uuid " + broadcasterName));
}
String subProtocol = (String) servletReq.getAttribute(FrameworkConfig.WEBSOCKET_SUBPROTOCOL);
final boolean waitForResource = waitFor == -1 ? true : false;
Broadcaster newBroadcaster;
// See issue https://github.com/Atmosphere/atmosphere/issues/676
synchronized (broadcasterName.intern()) {
newBroadcaster = config.getBroadcasterFactory().lookup(broadcasterName, true);
newBroadcaster.setBroadcasterLifeCyclePolicy(BroadcasterLifeCyclePolicy.EMPTY_DESTROY);
}
final Broadcaster bcaster = newBroadcaster;
if (!waitForResource || (!transport.startsWith(POLLING_TRANSPORT) && subProtocol == null)) {
final boolean resumeOnBroadcast = transport.equals(JSONP_TRANSPORT) || transport.equals(LONG_POLLING_TRANSPORT);
if (listeners != null) {
for (Class<? extends AtmosphereResourceEventListener> listener : listeners) {
try {
AtmosphereResourceEventListener el = atmosphereFramework.newClassInstance(AtmosphereResourceEventListener.class, listener);
r.addEventListener(el);
} catch (Throwable t) {
throw new WebApplicationException(
new IllegalStateException("Invalid AtmosphereResourceEventListener " + listener));
}
}
}
final Object entity = response.getEntity();
r.addEventListener(new OnSuspend() {
@Override
public void onSuspend(AtmosphereResourceEvent event) {
try {
if (entity != null) {
if (waitForResource) {
bcaster.awaitAndBroadcast(entity, 30, TimeUnit.SECONDS);
} else {
bcaster.broadcastOnResume(entity);
event.getResource().resume();
}
}
} finally {
event.getResource().removeEventListener(this);
}
}
});
if (resumeOnBroadcast) {
servletReq.setAttribute(RESUME_ON_BROADCAST, new Boolean(true));
}
r.setBroadcaster(bcaster);
executeSuspend(r, timeout, resumeOnBroadcast, null, request, response, writeEntity);
} else {
Object entity = response.getEntity();
if (waitForResource) {
bcaster.awaitAndBroadcast(entity, 30, TimeUnit.SECONDS);
} else {
bcaster.broadcast(entity);
}
if (subProtocol == null && writeEntity) {
try {
if (Callable.class.isAssignableFrom(entity.getClass())) {
entity = Callable.class.cast(entity).call();
}
synchronized (response) {
response.setEntity(entity);
response.write();
}
} catch (Throwable t) {
logger.debug("Error running Callable", t);
response.setEntity(null);
}
} else {
response.setEntity(null);
}
}
break;
case SUSPEND_RESPONSE:
SuspendResponse<?> s = SuspendResponse.class.cast(JResponseAsResponse.class.cast(response.getResponse()).getJResponse());
boolean resumeOnBroadcast = resumeOnBroadcast(s.resumeOnBroadcast());
for (AtmosphereResourceEventListener el : s.listeners()) {
r.addEventListener(el);
}
if (s.getEntity() == null) {
//https://github.com/Atmosphere/atmosphere/issues/423
response.setEntity("");
}
Broadcaster bc = s.broadcaster();
if (bc == null && s.scope() != Suspend.SCOPE.REQUEST) {
bc = (Broadcaster) servletReq.getAttribute(INJECTED_BROADCASTER);
}
suspend(resumeOnBroadcast,
translateTimeUnit(s.period().value(), s.period().timeUnit()), request, response, bc, r, s.scope(), s.writeEntity());
break;
case SUBSCRIBE:
case SUSPEND:
case SUSPEND_RESUME:
resumeOnBroadcast = resumeOnBroadcast((action == Action.SUSPEND_RESUME));
if (listeners != null) {
for (Class<? extends AtmosphereResourceEventListener> listener : listeners) {
try {
AtmosphereResourceEventListener el = atmosphereFramework.newClassInstance(AtmosphereResourceEventListener.class, listener);
r.addEventListener(el);
} catch (Throwable t) {
throw new WebApplicationException(
new IllegalStateException("Invalid AtmosphereResourceEventListener " + listener, t));
}
}
}
Broadcaster broadcaster = (Broadcaster) servletReq.getAttribute(INJECTED_BROADCASTER);
// @Subscribe
// TODO: Optimize me
if (action == Action.SUBSCRIBE) {
Class<Broadcaster> c = null;
try {
c = (Class<Broadcaster>) Class.forName((String) servletReq.getAttribute(BROADCASTER_CLASS));
} catch (Throwable e) {
throw new IllegalStateException(e.getMessage());
}
broadcaster = config.getBroadcasterFactory().lookup(c, topic, true);
}
suspend(resumeOnBroadcast, timeout, request, response,
broadcaster, r, scope, writeEntity);
break;
case RESUME:
if (response.getEntity() != null) {
try {
synchronized (response) {
response.write();
}
} catch (IOException ex) {
throw new WebApplicationException(ex);
}
}
String path = response.getContainerRequest().getPath();
r = resumeCandidates.remove(path.substring(path.lastIndexOf("/") + 1));
if (r != null) {
resume(r);
} else {
throw new WebApplicationException(
new IllegalStateException("Unable to retrieve suspended Response. " +
"Either session-support is not enabled in atmosphere.xml or the" +
"path used to resume is invalid."));
}
break;
case BROADCAST:
case PUBLISH:
case RESUME_ON_BROADCAST:
AtmosphereResource ar = (AtmosphereResource) servletReq.getAttribute(SUSPENDED_RESOURCE);
if (ar != null) {
r = ar;
}
if (action == Action.PUBLISH) {
Class<Broadcaster> c = null;
try {
c = (Class<Broadcaster>) Class.forName((String) servletReq.getAttribute(BROADCASTER_CLASS));
} catch (Throwable e) {
throw new IllegalStateException(e.getMessage());
}
r.setBroadcaster(config.getBroadcasterFactory().lookup(c, topic, true));
}
broadcast(response, r, timeout);
if (!writeEntity) {
synchronized (response) {
response.setEntity(null);
}
}
break;
case SCHEDULE:
case SCHEDULE_RESUME:
Object o = response.getEntity();
Broadcaster b = r.getBroadcaster();
if (response.getEntity() instanceof Broadcastable) {
b = ((Broadcastable) response.getEntity()).getBroadcaster();
o = ((Broadcastable) response.getEntity()).getMessage();
response.setEntity(((Broadcastable) response.getEntity()).getResponseMessage());
}
if (response.getEntity() != null) {
try {
synchronized (response) {
response.write();
}
} catch (IOException ex) {
throw new WebApplicationException(ex);
}
}
if (action == Action.SCHEDULE_RESUME) {
configureResumeOnBroadcast(b);
}
b.scheduleFixedBroadcast(o, waitFor, timeout, TimeUnit.SECONDS);
break;
}
return response;
}