package org.jacorb.poa; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.jacorb.orb.Delegate; import org.jacorb.orb.ORB; import org.jacorb.orb.dsi.ServerRequest; import org.jacorb.orb.giop.RequestInputStream; import org.jacorb.orb.miop.MIOPListener; import org.jacorb.orb.miop.MIOPProfile; import org.jacorb.poa.AGM.TGTCWrapper; import org.omg.CORBA.Policy; import org.omg.CORBA.portable.ObjectImpl; import org.omg.ETF.Factories; import org.omg.ETF.Profile; import org.omg.IOP.TAG_UIPMC; import org.omg.PortableGroup.NotAGroupObject; import org.omg.PortableGroup.TagGroupTaggedComponent; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAPackage.ObjectNotActive; import org.omg.PortableServer.POAPackage.WrongAdapter; import org.omg.PortableServer.POAPackage.WrongPolicy; import org.omg.RTCORBA.ProtocolProperties; import org.slf4j.Logger; /** * The Group Object Adapter. * * @author Alysson Neves Bessani * @version 1.0 * @see org.jacorb.poa.POA */ public class GOA extends org.jacorb.poa.POA implements org.omg.PortableGroup.GOA { private static final long serialVersionUID = -806217810084253929L; // Active Group Map private AGM agm; // Table for OIDs to port mappings private Map<byte[], MIOPProfile> portTable; private MIOPListener listener = null; private Logger logger; /** * Creates a new instance of GOA * * @param orb * @param name * @param parent * @param manager * @param policies */ public GOA (ORB orb, String name, org.jacorb.poa.POA parent, POAManager manager, Policy[] policies) { super (orb, name, parent, manager, policies); Factories f = orb.getTransportManager ().getFactories (TAG_UIPMC.value); logger = orb.getConfiguration ().getLogger("org.jacorb.poa"); if ( f != null) { listener = (MIOPListener)f.create_listener ((ProtocolProperties)null, 0, (short)0); agm = new AGM(); portTable = new HashMap<byte[], MIOPProfile> (); } } /** * Removes a member servant from this group. * * @param ref the group ref * @param oid the member servant oid * * @throws NotAGroupObject if ref is not a group reference */ public void disassociate_reference_with_id (org.omg.CORBA.Object ref, byte[] oid) throws NotAGroupObject { MIOPProfile profile = getMIOPProfile (ref); removeGroupMember (profile, oid); } /** * Add a member servant to this group * * @param ref the group ref * @param oid the member servant oid * * @throws NotAGroupObject if ref is not a group reference */ public void associate_reference_with_id (org.omg.CORBA.Object ref, byte[] oid) throws NotAGroupObject { MIOPProfile profile = getMIOPProfile (ref); addGroupMember (profile, oid); } /** * Create an oid member for this group. It must be used to register a servant * as member of the group with the activate_object_with_id() method. * * @param ref the group reference * @return ths created oid already member of this group * * @throws NotAGroupObject if ref is not a group reference */ public byte[] create_id_for_reference (org.omg.CORBA.Object ref) throws NotAGroupObject { MIOPProfile profile = getMIOPProfile (ref); // This method in POA is private, we must change byte[] oid = generateObjectId (); addGroupMember (profile, oid); return oid; } /** * Get the members of the group. * * @param ref the group ref * @return the group members oid * * @throws NotAGroupObject if ref is not a group reference */ public byte[][] reference_to_ids (org.omg.CORBA.Object ref) throws NotAGroupObject { return agm.getMembersFromGroup (getMIOPProfile (ref).getTagGroup ()); } /** * Process the group request through the POA tree. * * @param tagGroup the target group logical identification * @param request the request to be processed */ public void processGroupRequest (TagGroupTaggedComponent tagGroup, ServerRequest request) { // deliver the request for all members in this POA byte[][] members = agm.getMembersFromGroup (tagGroup); if (members.length > 0) { // get the ORB and the request buffer ORB orb = getORB (); byte[] buffer = request.getInputStream ().getBufferCopy (); for (int i = 0; i < members.length; i++) { ServerRequest requestClone = new ServerRequest (orb, new RequestInputStream (orb, request.getConnection (), buffer), request.getConnection ()); try { byte[] oid = members[i]; org.omg.CORBA.Object member = id_to_reference (oid); Delegate delegate = (Delegate)((ObjectImpl)member)._get_delegate (); requestClone.setObjectKey (delegate.getObjectKey ()); _invoke (requestClone); } catch (WrongAdapter ex) { logger.error ("Caught exception processing group request", ex); } catch (ObjectNotActive ex) { logger.error ("Caught exception processing group request", ex); } catch (WrongPolicy ex) { logger.error ("Caught exception processing group request", ex); } catch( org.omg.CORBA.SystemException ex) { logger.error ("Caught SystemException processing group request", ex); } catch( RuntimeException ex) { logger.error ("Caught unknown exception processing group request", ex); } } } // propagates the request to the children POAs POA children[] = the_children (); for (int i = 0; i < children.length; i++) { ((GOA)children[i]).processGroupRequest (tagGroup, request); } } /** * Try to get the MIOP profile of an object reference. * * @param ref the group ref * @return the MIOP profile of the ref * * @throws NotAGroupObject if the ref doesn't have a MIOP profile */ private MIOPProfile getMIOPProfile (org.omg.CORBA.Object ref) throws NotAGroupObject { Delegate delegate = (Delegate)((ObjectImpl)ref)._get_delegate (); Profile profile = delegate.getParsedIOR ().getEffectiveProfile (); if (profile instanceof MIOPProfile) { return (MIOPProfile)profile; } else { throw new NotAGroupObject (ref.toString ()); } } /** * Add a member to this group. * * @param profile the group profile * @param oid the member oid */ private final void addGroupMember (MIOPProfile profile, byte[] oid) { int nMembers = agm.addToGroup (profile.getTagGroup (), oid); if ((nMembers == 1) && !listener.haveGroupConnection (profile.getUIPMCProfile ().the_port)) { // if this guy is the first member of the group and there is a multicast listener // port for that I will create it listener.addGroupConnection (profile); } portTable.put (oid, profile); } /** * Remove a member from this group. * * @param profile the group profile * @param oid the member oid */ private final void removeGroupMember (MIOPProfile profile, byte[] oid) { if (agm.removeFromGroup (profile.getTagGroup (), oid) == 0) { // if this member was last in the group remove the group // from multicast listener listener.removeGroupConnection (profile.getUIPMCProfile ().the_port); } portTable.remove (oid); } /** * This method is used only in deactivate_object method * for group members deactivation * * @param oid the member oid */ void clearGroupRegistration (byte[] oid) { if (agm != null) { ArrayList<TGTCWrapper> groupsKeys = agm.getGroupsWithMember (oid); for (int i = 0; i < groupsKeys.size(); i++) { if (agm.removeFromGroup (groupsKeys.get (i).tcgtc, oid) == 0) { // If this member was last in the group remove the group // from the multicast listener listener.removeGroupConnection (portTable.get (oid).getUIPMCProfile ().the_port); } } } } }