final RequestServiceMessage reqSrv = (RequestServiceMessage) msg;
final String serviceID = reqSrv.getServiceID();
final RemoteServiceRegistration reg = getServiceRegistration(serviceID);
final DeliverServiceMessage m = reg.getDeliverServiceMessage();
m.setXID(reqSrv.getXID());
m.setServiceID(reqSrv.getServiceID());
return m;
}
case RemoteOSGiMessage.LEASE_UPDATE: {
final LeaseUpdateMessage suMsg = (LeaseUpdateMessage) msg;
final String serviceID = suMsg.getServiceID();
final short stateUpdate = suMsg.getType();
final String serviceURI = getRemoteAddress()
.resolve("#" + serviceID).toString();
switch (stateUpdate) {
case LeaseUpdateMessage.TOPIC_UPDATE: {
// There is an older r-OSGi version that incorrectly sends an ArrayList
// (1.0.0.RC4_v20131016-1848)
Object topicsAdded = suMsg.getPayload()[0];
if (topicsAdded instanceof List) {
topicsAdded = ((List) topicsAdded).toArray(new String[0]);
}
Object topicsRemoved = suMsg.getPayload()[1];
if (topicsRemoved instanceof List) {
topicsRemoved = ((List) topicsRemoved).toArray(new String[0]);
}
updateTopics((String[]) topicsAdded, (String[]) topicsRemoved);
return null;
}
case LeaseUpdateMessage.SERVICE_ADDED: {
final Dictionary properties = (Dictionary) suMsg.getPayload()[1];
sanitizeServiceProperties(properties, serviceURI);
final RemoteServiceReferenceImpl ref = new RemoteServiceReferenceImpl(
(String[]) suMsg.getPayload()[0], serviceID,
properties, this);
remoteServices.put(serviceURI, ref);
RemoteOSGiServiceImpl
.notifyRemoteServiceListeners(new RemoteServiceEvent(
RemoteServiceEvent.REGISTERED, ref));
return null;
}
case LeaseUpdateMessage.SERVICE_MODIFIED: {
final Dictionary properties = (Dictionary) suMsg.getPayload()[1];
sanitizeServiceProperties(properties, serviceURI);
final ServiceRegistration reg = (ServiceRegistration) proxiedServices
.get(serviceID);
if (reg != null) {
reg.setProperties(properties);
}
final RemoteServiceReferenceImpl ref = getRemoteReference(serviceURI); //$NON-NLS-1$
// If r-OSGi receives a SERVICE_MODIFIED for service X before it
// knows about X (SERVICE_ADDED), there is no point in updating
// the local service instance. It will fail with an NPE anyway.
// (see https://bugs.eclipse.org/420433)
if (ref == null && reg == null) {
return null;
}
ref.setProperties(properties);
RemoteOSGiServiceImpl
.notifyRemoteServiceListeners(new RemoteServiceEvent(
RemoteServiceEvent.MODIFIED, ref));
return null;
}
case LeaseUpdateMessage.SERVICE_REMOVED: {
if (networkChannel == null) {
return null;
}
final RemoteServiceReference ref = (RemoteServiceReference) remoteServices
.remove(serviceURI);
if (ref != null) {
RemoteOSGiServiceImpl
.notifyRemoteServiceListeners(new RemoteServiceEvent(
RemoteServiceEvent.UNREGISTERING, ref));
}
final Bundle bundle = (Bundle) proxyBundles.remove(serviceID);
if (bundle != null) {
try {
bundle.uninstall();
} catch (final BundleException be) {
be.printStackTrace();
}
proxiedServices.remove(serviceID);
remoteServices.remove(serviceURI); //$NON-NLS-1$
}
return null;
}
}
return null;
}
case RemoteOSGiMessage.REMOTE_CALL: {
final RemoteCallMessage invMsg = (RemoteCallMessage) msg;
try {
RemoteServiceRegistration serv = (RemoteServiceRegistration) localServices
.get(invMsg.getServiceID());
if (serv == null) {
final RemoteServiceRegistration reg = getServiceRegistration(invMsg
.getServiceID());
if (reg == null) {
throw new IllegalStateException(toString()
+ "Could not get " + invMsg.getServiceID() //$NON-NLS-1$
+ ", known services " + localServices); //$NON-NLS-1$
} else {
serv = reg;
}
}
// get the invocation arguments and the local method
final Object[] arguments = invMsg.getArgs();
for (int i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof InputStreamHandle) {
arguments[i] = getInputStreamProxy((InputStreamHandle) arguments[i]);
} else if (arguments[i] instanceof OutputStreamHandle) {
arguments[i] = getOutputStreamProxy((OutputStreamHandle) arguments[i]);
}
}
final Method method = serv.getMethod(invMsg
.getMethodSignature());
// invoke method
try {
Object result = method.invoke(serv.getServiceObject(),
arguments);
final RemoteCallResultMessage m = new RemoteCallResultMessage();
m.setXID(invMsg.getXID());
if (result instanceof InputStream) {
m
.setResult(getInputStreamPlaceholder((InputStream) result));
} else if (result instanceof OutputStream) {
m
.setResult(getOutputStreamPlaceholder((OutputStream) result));
} else {
m.setResult(result);
}
return m;
} catch (final InvocationTargetException t) {
t.printStackTrace();
throw t.getTargetException();
}
} catch (final Throwable t) {
// TODO: send to log
t.printStackTrace();
final RemoteCallResultMessage m = new RemoteCallResultMessage();
m.setXID(invMsg.getXID());
m.setException(t);
return m;
}
}
case RemoteOSGiMessage.REMOTE_EVENT: {
final RemoteEventMessage eventMsg = (RemoteEventMessage) msg;
final Dictionary properties = eventMsg.getProperties();
// transform the event timestamps
final Long remoteTs;
if ((remoteTs = (Long) properties.get(EventConstants.TIMESTAMP)) != null) {
properties.put(EventConstants.TIMESTAMP, getOffset().transform(
remoteTs));
}
final Event event = new Event(eventMsg.getTopic(), properties);
// and deliver the event to the local framework
if (RemoteOSGiServiceImpl.eventAdminTracker.getTrackingCount() > 0) {
((EventAdmin) RemoteOSGiServiceImpl.eventAdminTracker
.getService()).postEvent(event);
} else {
// TODO: to log
System.err.println("Could not deliver received event: " + event //$NON-NLS-1$
+ ". No EventAdmin available."); //$NON-NLS-1$
}
return null;
}
case RemoteOSGiMessage.TIME_OFFSET: {
// add timestamp to the message and return the message to sender
((TimeOffsetMessage) msg).timestamp();
return msg;
}
case RemoteOSGiMessage.STREAM_REQUEST: {
final StreamRequestMessage reqMsg = (StreamRequestMessage) msg;
try {
// fetch stream object
final Object stream = streams.get(new Integer(reqMsg
.getStreamID()));
if (stream == null) {
throw new IllegalStateException(
"Could not get stream with ID " //$NON-NLS-1$
+ reqMsg.getStreamID());
}
// invoke operation on stream
switch (reqMsg.getOp()) {
case StreamRequestMessage.READ: {
final int result = ((InputStream) stream).read();
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult((short) result);
return m;
}
case StreamRequestMessage.READ_ARRAY: {
final byte[] b = new byte[reqMsg.getLenOrVal()];
final int len = ((InputStream) stream).read(b, 0, reqMsg
.getLenOrVal());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_ARRAY);
m.setLen(len);
if (len > 0) {
m.setData(b);
}
return m;
}
case StreamRequestMessage.WRITE: {
((OutputStream) stream).write(reqMsg.getLenOrVal());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_WRITE_OK);
return m;
}
case StreamRequestMessage.WRITE_ARRAY: {
((OutputStream) stream).write(reqMsg.getData());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_WRITE_OK);
return m;
}
default:
throw new RemoteOSGiException(
"Unimplemented op code for stream request " + msg); //$NON-NLS-1$
}
} catch (final IOException e) {
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_EXCEPTION);
m.setException(e);
return m;
}
}
case RemoteOSGiMessage.REQUEST_BUNDLE:
final RequestBundleMessage reqB = (RequestBundleMessage) msg;