package com.workshare.msnos.core; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import javax.annotation.concurrent.GuardedBy; import com.workshare.msnos.core.protocols.ip.Endpoint; import com.workshare.msnos.core.protocols.ip.Endpoint.Type; import com.workshare.msnos.soup.json.Json; public class RemoteAgent extends RemoteEntity implements Agent { public static final Set<Endpoint> NO_ENDPOINTS = Collections.emptySet(); private final Ring ring; @GuardedBy("this") private Set<Endpoint> endpoints; @GuardedBy("this") private transient Map<Type, Set<Endpoint>> endpointsByType; public RemoteAgent(UUID uuid, Cloud cloud, Set<Endpoint> endpoints) { this(uuid, cloud, endpoints, Ring.make(endpoints)); } private RemoteAgent(UUID uuid, Cloud cloud, Set<Endpoint> endpoints, Ring ring) { super(new Iden(Iden.Type.AGT, uuid), cloud); this.ring = ring; update(endpoints); } @Override public synchronized Set<Endpoint> getEndpoints() { return endpoints; } public synchronized Set<Endpoint> getEndpoints(Type type) { return endpointsByType.get(type); } @Override public Ring getRing() { return ring; } @Override public String toString() { return Json.toJsonString(this); } @Override public boolean equals(Object other) { try { return this.getIden().equals(((Agent) (other)).getIden()); } catch (Exception any) { return false; } } @Override public int hashCode() { return getIden().hashCode(); } public void update(Set<Endpoint> newEndpoints) { touch(); synchronized(this) { this.endpoints = createImmutableSet(newEndpoints); this.endpointsByType = createImmutableByTypeMap(endpoints); } } private Map<Type, Set<Endpoint>> createImmutableByTypeMap(Set<Endpoint> newEndpoints) { Map<Type, Set<Endpoint>> byType = new HashMap<Type, Set<Endpoint>>(); for (Endpoint point : newEndpoints) { Type type = point.getType(); Set<Endpoint> points = byType.get(type); if (points == null) { points = new HashSet<Endpoint>(); byType.put(type, points); } points.add(point); } for(Type type : Type.values()) { Set<Endpoint> points = createImmutableSet(byType.get(type)); byType.put(type, Collections.unmodifiableSet(points)); } return Collections.unmodifiableMap(byType); } private Set<Endpoint> createImmutableSet(Set<Endpoint> endpoints) { if (endpoints == null) return NO_ENDPOINTS; else return Collections.unmodifiableSet(new HashSet<Endpoint>(endpoints)); } }