package xdi2.agent.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xdi2.agent.XDIAgent; import xdi2.agent.routing.XDIAgentRouter; import xdi2.client.XDIClientRoute; import xdi2.client.exceptions.Xdi2AgentException; import xdi2.client.exceptions.Xdi2ClientException; import xdi2.client.impl.XDIAbstractClientRoute; import xdi2.client.manipulator.Manipulator; import xdi2.core.ContextNode; import xdi2.core.features.nodetypes.XdiPeerRoot; import xdi2.core.syntax.XDIAddress; import xdi2.core.syntax.XDIArc; import xdi2.core.util.XDIAddressUtil; import xdi2.messaging.Message; import xdi2.messaging.MessageEnvelope; public class XDIBasicAgent implements XDIAgent { private static final Logger log = LoggerFactory.getLogger(XDIBasicAgent.class); private LinkedList<XDIAgentRouter<?, ?>> agentRouters; private Collection<Manipulator> manipulators; public XDIBasicAgent(Collection<XDIAgentRouter<?, ?>> agentRouters) { this.agentRouters = new LinkedList<XDIAgentRouter<?, ?>> (agentRouters); this.manipulators = new ArrayList<Manipulator> (); } public XDIBasicAgent(XDIAgentRouter<?, ?>[] agentRouters) { this.agentRouters = new LinkedList<XDIAgentRouter<?, ?>> (Arrays.asList(agentRouters)); this.manipulators = new ArrayList<Manipulator> (); } public XDIBasicAgent(XDIAgentRouter<?, ?> agentRouter) { this.agentRouters = new LinkedList<XDIAgentRouter<?, ?>> (); this.agentRouters.add(agentRouter); this.manipulators = new ArrayList<Manipulator> (); } public XDIBasicAgent() { this.agentRouters = new LinkedList<XDIAgentRouter<?, ?>> (); this.manipulators = new ArrayList<Manipulator> (); } @Override public XDIClientRoute<?> route(XDIArc toPeerRootXDIArc) throws Xdi2AgentException { // let's find a route XDIClientRoute<?> foundRoute = null; XDIAgentRouter<?, ?> foundAgentRouter = null; for (XDIAgentRouter<?, ?> agentRouter : this.getAgentRouters()) { if (log.isDebugEnabled()) log.debug("Trying router " + agentRouter.getClass().getSimpleName() + " to route to " + toPeerRootXDIArc); foundRoute = agentRouter.route(toPeerRootXDIArc); if (foundRoute != null) foundAgentRouter = agentRouter; if (foundRoute != null) break; } if (foundRoute == null) { if (log.isDebugEnabled()) log.debug("No route found for " + toPeerRootXDIArc); return null; } if (log.isDebugEnabled()) log.debug("Route for " + toPeerRootXDIArc + " is " + foundRoute + " via router " + foundAgentRouter.getClass().getSimpleName()); // add manipulators if supported if (foundRoute instanceof XDIAbstractClientRoute && this.getManipulators() != null) { ((XDIAbstractClientRoute<?>) foundRoute).getManipulators().addAll(this.getManipulators()); } // done return foundRoute; } @Override public XDIClientRoute<?> route(XDIAddress XDIaddress) throws Xdi2AgentException, Xdi2ClientException { // let's find out the TO peer root of the address XDIAddress peerRootXDIAddress = XDIAddressUtil.extractXDIAddress(XDIaddress, XdiPeerRoot.class, false, false, true, false, false); XDIArc peerRootFirstXDIArc = peerRootXDIAddress == null ? null : peerRootXDIAddress.getFirstXDIArc(); XDIArc firstXDIArc = XDIaddress.getFirstXDIArc(); if (log.isDebugEnabled()) log.debug("Peer root first arc: " + peerRootFirstXDIArc + ", First arc: " + firstXDIArc); XDIArc toPeerRootXDIArc = null; if (toPeerRootXDIArc == null && peerRootFirstXDIArc != null) toPeerRootXDIArc = peerRootFirstXDIArc; if (toPeerRootXDIArc == null && firstXDIArc != null) toPeerRootXDIArc = XdiPeerRoot.createPeerRootXDIArc(XDIAddress.fromComponent(firstXDIArc)); if (log.isDebugEnabled()) log.debug("Determined TO peer root: " + toPeerRootXDIArc); if (toPeerRootXDIArc == null) { if (log.isDebugEnabled()) log.debug("Unable to determine TO peer root for address " + XDIaddress); return null; } // let's find a route return route(toPeerRootXDIArc); } @Override public XDIClientRoute<?> route(MessageEnvelope messageEnvelope) throws Xdi2AgentException { // use the TO peer root XDIArc toPeerRootXDIArc = null; for (Message message : messageEnvelope.getMessages()) { if (toPeerRootXDIArc == null) { toPeerRootXDIArc = message.getToPeerRootXDIArc(); continue; } if (! toPeerRootXDIArc.equals(message.getToPeerRootXDIArc())) { throw new Xdi2AgentException("Cannot route message envelope with multiple messages and different TO peer roots."); } } // let's find a route return route(toPeerRootXDIArc); } @Override public XDIClientRoute<?> route(Message message) throws Xdi2AgentException, Xdi2ClientException { // use the TO peer root XDIArc toPeerRootXDIArc = message.getToPeerRootXDIArc(); // let's find a route return route(toPeerRootXDIArc); } /* * $get helper methods */ @Override public ContextNode get(XDIAddress XDIaddress, XDIAddress senderXDIAddress, Collection<Manipulator> manipulators) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, senderXDIAddress, manipulators); } @Override public ContextNode get(XDIAddress XDIaddress, XDIAddress senderXDIAddress, Manipulator[] manipulators) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, senderXDIAddress, manipulators); } @Override public ContextNode get(XDIAddress XDIaddress, XDIAddress senderXDIAddress, Manipulator manipulator) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, senderXDIAddress, manipulator); } @Override public ContextNode get(XDIAddress XDIaddress, XDIAddress senderXDIAddress) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, senderXDIAddress); } @Override public ContextNode get(XDIAddress XDIaddress, Collection<Manipulator> manipulators) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, manipulators); } @Override public ContextNode get(XDIAddress XDIaddress, Manipulator[] manipulators) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, manipulators); } @Override public ContextNode get(XDIAddress XDIaddress, Manipulator manipulator) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress, manipulator); } @Override public ContextNode get(XDIAddress XDIaddress) throws Xdi2AgentException, Xdi2ClientException { XDIClientRoute<?> xdiClientRoute = this.route(XDIaddress); if (xdiClientRoute == null) return null; return xdiClientRoute.get(XDIaddress); } /* * Getters and setters */ public LinkedList<XDIAgentRouter<?, ?>> getAgentRouters() { return this.agentRouters; } public void setAgentRouters(LinkedList<XDIAgentRouter<?, ?>> agentRouters) { this.agentRouters = agentRouters; } public Collection<Manipulator> getManipulators() { return this.manipulators; } public void setManipulators(Collection<Manipulator> manipulators) { this.manipulators = manipulators; } }