/**
* Copyright (c) 2006 Ecliptical Software Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ecliptical Software Inc. - initial API and implementation
*/
package org.eclipse.ecf.pubsub.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.ecf.core.events.IContainerConnectedEvent;
import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.sharedobject.ISharedObject;
import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContext;
import org.eclipse.ecf.core.sharedobject.ISharedObjectManager;
import org.eclipse.ecf.core.sharedobject.ReplicaSharedObjectDescription;
import org.eclipse.ecf.core.sharedobject.SharedObjectInitException;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectActivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectDeactivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.util.Event;
import org.eclipse.ecf.example.pubsub.SerializationUtil;
import org.eclipse.ecf.pubsub.IPublishedService;
import org.eclipse.ecf.pubsub.PublishedServiceDescriptor;
public class DiscoveryAgent extends PlatformObject implements ISharedObject {
protected static final Object DIRECTORY_KEY = new Integer(0);
protected ISharedObjectConfig config;
protected PublishedServiceDirectory directory;
public void init(ISharedObjectConfig config) throws SharedObjectInitException {
if (config.getContext().getLocalContainerID().equals(config.getHomeContainerID())) {
directory = (PublishedServiceDirectory) config.getProperties().get(DIRECTORY_KEY);
if (directory == null)
throw new SharedObjectInitException("Directory is required.");
}
this.config = config;
}
public void handleEvent(Event event) {
if (event instanceof ISharedObjectActivatedEvent) {
ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
if (e.getActivatedID().equals(config.getSharedObjectID()))
activated();
else
activated(e.getActivatedID());
} else if (event instanceof ISharedObjectDeactivatedEvent) {
ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
if (e.getDeactivatedID().equals(config.getSharedObjectID()))
deactivated();
else
deactivated(e.getDeactivatedID());
} else if (event instanceof IContainerConnectedEvent) {
IContainerConnectedEvent e = (IContainerConnectedEvent) event;
if (e.getTargetID().equals(e.getLocalContainerID()))
connected();
else
connected(e.getTargetID());
} else if (event instanceof IContainerDisconnectedEvent) {
IContainerDisconnectedEvent e = (IContainerDisconnectedEvent) event;
if (e.getTargetID().equals(e.getLocalContainerID()))
disconnected();
else
disconnected(e.getTargetID());
} else if (event instanceof ISharedObjectMessageEvent)
received((ISharedObjectMessageEvent) event);
}
protected boolean isConnected() {
return config.getContext().getConnectedID() != null;
}
protected boolean isPrimary() {
return config.getContext().getLocalContainerID().equals(config.getHomeContainerID());
}
protected void activated(ID sharedObjectID) {
if (isPrimary())
return;
ISharedObjectContext ctx = config.getContext();
Object object = ctx.getSharedObjectManager().getSharedObject(sharedObjectID);
if (object instanceof IPublishedService) {
IPublishedService svc = (IPublishedService) object;
Map props = svc.getProperties();
PublishedServiceDescriptor desc = new PublishedServiceDescriptor(ctx.getLocalContainerID(), sharedObjectID, props);
try {
ctx.sendMessage(config.getHomeContainerID(), SerializationUtil.serialize(new DiscoveryMessage(DiscoveryMessage.ADDED, desc)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void activated() {
if (isConnected())
connected();
}
protected void deactivated(ID sharedObjectID) {
if (isPrimary())
return;
ISharedObjectContext ctx = config.getContext();
Object object = ctx.getSharedObjectManager().getSharedObject(sharedObjectID);
if (object instanceof IPublishedService) {
IPublishedService svc = (IPublishedService) object;
Map props = svc.getProperties();
PublishedServiceDescriptor desc = new PublishedServiceDescriptor(ctx.getLocalContainerID(), sharedObjectID, props);
try {
ctx.sendMessage(config.getHomeContainerID(), SerializationUtil.serialize(new DiscoveryMessage(DiscoveryMessage.REMOVED, desc)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void deactivated() {
if (isPrimary() && isConnected())
try {
config.getContext().sendDispose(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void connected(ID containerID) {
if (isPrimary())
try {
config.getContext().sendCreate(containerID, new ReplicaSharedObjectDescription(getClass(), config.getSharedObjectID()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void connected() {
if (isPrimary()) {
try {
config.getContext().sendCreate(null, new ReplicaSharedObjectDescription(getClass(), config.getSharedObjectID()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
ArrayList published = new ArrayList();
ISharedObjectContext ctx = config.getContext();
ISharedObjectManager mgr = ctx.getSharedObjectManager();
ID[] ids = mgr.getSharedObjectIDs();
ID containerID = ctx.getLocalContainerID();
for (int i = 0; i < ids.length; ++i) {
Object object = mgr.getSharedObject(ids[i]);
if (object instanceof IPublishedService) {
IPublishedService svc = (IPublishedService) object;
Map props = svc.getProperties();
published.add(new PublishedServiceDescriptor(containerID, ids[i], props));
}
}
if (published.isEmpty())
return;
PublishedServiceDescriptor[] descriptors = new PublishedServiceDescriptor[published.size()];
published.toArray(descriptors);
try {
ctx.sendMessage(config.getHomeContainerID(), SerializationUtil.serialize(new DiscoveryMessage(DiscoveryMessage.ADDED, descriptors)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void disconnected(ID containerID) {
if (containerID.equals(config.getHomeContainerID()))
config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
}
protected void disconnected() {
config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
}
protected void received(ISharedObjectMessageEvent event) {
Object data = event.getData();
if (!(data instanceof byte[]))
return;
try {
data = SerializationUtil.deserialize((byte[]) data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
if (!(data instanceof DiscoveryMessage))
return;
directory.handleDiscovery(event.getRemoteContainerID(), (DiscoveryMessage) data);
}
public void handleEvents(Event[] events) {
for (int i = 0; i < events.length; ++i)
handleEvent(events[i]);
}
public void dispose(ID containerID) {
config = null;
directory = null;
}
}