package org.apache.muse.management.muse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.namespace.QName;
import org.apache.muse.core.routing.ResourceRouter;
import org.apache.muse.management.binding.Binding;
import org.apache.muse.management.common.Contribution;
import org.apache.muse.ws.addressing.soap.SoapFault;
import org.apache.muse.ws.dm.muws.MuwsConstants;
import org.apache.muse.ws.dm.muws.Participant;
import org.apache.muse.ws.dm.muws.RelationshipType;
import org.apache.muse.ws.dm.muws.Relationships;
import org.apache.muse.ws.dm.muws.impl.SimpleParticipant;
import org.apache.muse.ws.dm.muws.impl.SimpleRelationshipType;
import org.apache.muse.ws.resource.WsResource;
import org.eclipse.corona.management.osgi.BundleContribution;
import org.eclipse.corona.management.osgi.ServiceContribution;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
public class ManagementBinding implements Binding, ServiceFactory {
private static ManagementBinding _instance = new ManagementBinding();
public static ManagementBinding getDefault(){ return _instance; }
private ResourceRouter _router;
private ArrayList pendingContributions = new ArrayList();
private HashMap resourceForContribution = new HashMap();
//Hide constructor
private ManagementBinding(){}
public void bindContribution(Contribution contribution) {
if(_router == null){
synchronized(pendingContributions){
pendingContributions.add(contribution);
}
return;
}
ManagementResourceRouter router = (ManagementResourceRouter)_router;
//make an EPR
try {
WsResource resource = (WsResource)router.addNewResource(contribution);
resourceForContribution.put(contribution, resource);
if(contribution instanceof BundleContribution){
handleBundleDependencies((BundleContribution)contribution, resource);
} else if(contribution instanceof ServiceContribution){
handleServiceRelationships((ServiceContribution)contribution, resource);
}
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setResourceRouter(ResourceRouter router){
this._router = router;
handlePendingContributions();
}
private void handlePendingContributions(){
synchronized(pendingContributions){
if(!pendingContributions.isEmpty()){
Iterator i = pendingContributions.iterator();
while(i.hasNext()){
bindContribution((Contribution)i.next());
}
}
pendingContributions.clear();
}
}
private void handleBundleDependencies(BundleContribution contribution, WsResource resource){
try {
Relationships relCap = (Relationships)resource.getCapability(MuwsConstants.RELATIONSHIPS_URI);
if(relCap == null){
return;
}
BundleContribution[] dependencies = contribution.getBundleDependents();
if(dependencies == null) return;
for(int i=0;i<dependencies.length;i++){
BundleContribution dependency = dependencies[i];
WsResource targetResource = (WsResource)resourceForContribution.get(dependency);
if(targetResource == null){
continue;
}
Participant[] participants = new Participant[2];
QName typeNames[] = {new QName("http://resource.management.osgi/Bundle","Requires","osgi")};
RelationshipType type = new SimpleRelationshipType(typeNames);
participants[0] = new SimpleParticipant(resource, "required");
participants[1] = new SimpleParticipant(targetResource, "requires");
relCap.addRelationship("Bundle Requirement", type, participants);
}
} catch(Throwable t){
t.printStackTrace();
}
}
private void handleServiceRelationships(ServiceContribution contribution, WsResource resource){
try {
Relationships relCap = (Relationships)resource.getCapability(MuwsConstants.RELATIONSHIPS_URI);
if(relCap == null) return;
BundleContribution provider = contribution.getServiceProvider();
if(provider != null){
WsResource targetResource = (WsResource)resourceForContribution.get(provider);
if(targetResource != null){
Participant[] participants = new Participant[2];
QName typeNames[] = {new QName("http://resource.management.osgi/Service","ServiceProvider","osgi")};
RelationshipType type = new SimpleRelationshipType(typeNames);
participants[0] = new SimpleParticipant(resource, "service");
participants[1] = new SimpleParticipant(targetResource, "provider");
relCap.addRelationship("ServiceConsumer", type, participants);
//Now add reciprocal relationship to the bundle resource
relCap = (Relationships)targetResource.getCapability(MuwsConstants.RELATIONSHIPS_URI);
participants = new Participant[2];
QName serviceTypeNames[] = {new QName("http://resource.management.osgi/Bundle","RegisteredService","osgi")};
type = new SimpleRelationshipType(serviceTypeNames);
participants[0] = new SimpleParticipant(resource, "service");
participants[1] = new SimpleParticipant(targetResource, "provider");
relCap.addRelationship("RegisteredService", type, participants);
}
}
BundleContribution[] consumers = contribution.getServiceConsumers();
if(consumers == null) return;
for(int i=0;i<consumers.length;i++){
BundleContribution dependency = consumers[i];
WsResource targetResource = (WsResource)resourceForContribution.get(dependency);
if(targetResource == null){
continue;
}
Participant[] participants = new Participant[2];
QName typeNames[] = {new QName("http://resource.management.osgi/Service","ServiceConsumer")};
RelationshipType type = new SimpleRelationshipType(typeNames);
participants[0] = new SimpleParticipant(resource, "service");
participants[1] = new SimpleParticipant(targetResource, "consumer");
relCap.addRelationship("Service Consumer", type, participants);
}
} catch(Throwable t){
t.printStackTrace();
}
}
public Object getService(Bundle bundle, ServiceRegistration registration) {
return this;
}
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
//not much to do here...
}
public void unbindContribution(Contribution contribution) {
//TODO need to clean up relationships as well?
if(_router == null){
synchronized(pendingContributions){
pendingContributions.remove(contribution);
}
return;
}
ManagementResourceRouter router = (ManagementResourceRouter)_router;
try {
WsResource resource = (WsResource)resourceForContribution.get(contribution);
if(resource != null){
resource.shutdown();
}
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}