blob: 6a865c643ae7262f5eba68f6fbf80f74531e789c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* ssmith - initial
******************************************************************************/
package org.eclipse.persistence.jpa.rs.websockets;
import static org.eclipse.persistence.jaxb.JAXBContext.MEDIA_TYPE;
import java.beans.PropertyChangeListener;
import java.io.StringWriter;
import java.util.logging.Logger;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.util.LinkAdapter;
import org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.DefaultWebSocket;
import com.sun.grizzly.websockets.ProtocolHandler;
import com.sun.grizzly.websockets.WebSocketListener;
public class JPARSWebSocket extends DefaultWebSocket {
static final Logger logger = Logger.getLogger("JPARSWebSocket");
private Registration registration;
private ApplicationListener listener;
public JPARSWebSocket(ProtocolHandler handler, WebSocketListener[] listeners) {
super(handler, listeners);
}
public Registration getRegistration() {
return registration;
}
public void setRegistration(Registration registration) {
this.registration = registration;
}
public void setApplication(PersistenceContext context) {
this.listener = new ApplicationListener(this, context);
this.listener.register();
}
@Override
public void onClose(DataFrame frame) {
if (this.listener != null) {
this.listener.unregister();
}
super.onClose(frame);
}
public void sendInsert(PersistenceContext application, Object entity) {
send(application, entity);
}
public void sendUpdate(PersistenceContext application, Object entity) {
send(application, entity);
}
protected void send(PersistenceContext application, Object entity) {
String entityName = Helper.getShortClassName(entity.getClass());
if (ofInterest(application, entity, entityName)) {
String json = marshallEntity(application, entity);
if (json == null) {
logger.severe("Entity did not marshall, not sending: " + entity);
} else {
String wrappedJson =
"{" +
"\"url\" : \"persistence/" + application.getName() + "/" + entityName + "\", " +
"\"data\" : " + json +
"}";
logger.info(this + " sending: " + wrappedJson);
send(wrappedJson);
}
}
}
/**
* Answer whether the socket should send the update. The application name must
* match but the entity name is optional and will only be used if not null. This
* allows clients to register interest in changes to all entities in an application.
*
* @param application
* @param entity
* @param entityName
* @return
*/
private boolean ofInterest(PersistenceContext application, Object entity, String entityName) {
String appName = application.getName();
if ((appName == null) || (getRegistration() == null)) {
return false;
}
boolean appNameMatches = appName.equals(getRegistration().getAppName());
boolean entityNameMatches = (getRegistration().getEntityName() == null)
|| (getRegistration().getEntityName().equals(entityName));
return appNameMatches && entityNameMatches;
}
protected String marshallEntity(PersistenceContext context, Object entity) {
try {
Marshaller marshaller = StreamingOutputMarshaller.createMarshaller(context, MediaType.APPLICATION_JSON_TYPE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(entity, stringWriter);
String jsonString = stringWriter.toString();
return jsonString;
} catch (Exception e) {
logger.severe("Failed to marshall object: " + entity + ", exception: " + e.getMessage());
return null;
}
}
}