geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/management AbstractManagedObject.java
Date Thu, 21 Aug 2003 04:32:13 GMT
dain        2003/08/20 21:32:13

  Added:       modules/core/src/java/org/apache/geronimo/management
                        AbstractManagedObject.java
  Log:
  Initial revision of a basic ManagedObject implementation.
  
  Revision  Changes    Path
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/management/AbstractManagedObject.java
  
  Index: AbstractManagedObject.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.management;
  
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  import java.util.HashSet;
  import javax.management.InstanceNotFoundException;
  import javax.management.MBeanNotificationInfo;
  import javax.management.MBeanRegistration;
  import javax.management.MBeanServer;
  import javax.management.MBeanServerNotification;
  import javax.management.Notification;
  import javax.management.NotificationBroadcasterSupport;
  import javax.management.NotificationFilterSupport;
  import javax.management.NotificationListener;
  import javax.management.ObjectName;
  import javax.management.ReflectionException;
  import javax.management.relation.InvalidRelationIdException;
  import javax.management.relation.InvalidRoleValueException;
  import javax.management.relation.RelationNotFoundException;
  import javax.management.relation.RelationNotification;
  import javax.management.relation.RelationServiceMBean;
  import javax.management.relation.RelationServiceNotRegisteredException;
  import javax.management.relation.RelationTypeNotFoundException;
  import javax.management.relation.Role;
  import javax.management.relation.RoleInfo;
  import javax.management.relation.RoleList;
  import javax.management.relation.RoleNotFoundException;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.geronimo.deployment.dependency.DependencyServiceMBean;
  import org.apache.geronimo.deployment.service.MBeanRelationship;
  import org.apache.geronimo.jmx.JMXUtil;
  import org.apache.geronimo.management.NotificationType;
  import org.apache.geronimo.management.State;
  import org.apache.geronimo.management.StateManageable;
  import org.apache.geronimo.common.StartException;
  import org.apache.geronimo.common.StopException;
  
  /**
   * Abstract implementation of JSR77 StateManageable.
   * Implementors of StateManageable may use this class and simply provide
   * doStart, doStop and doNotification methods.
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/21 04:32:13 $
   */
  public abstract class AbstractManagedObject extends NotificationBroadcasterSupport implements
ManagedObject, StateManageable, EventProvider, NotificationListener, MBeanRegistration {
      protected final Log log = LogFactory.getLog(getClass());
  
      /**
       * The mbean server in which this server is registered.
       */
      protected MBeanServer server;
  
      /**
       * The unique name of this service.
       */
      protected ObjectName objectName;
  
      /**
       * The definitive list of notifications types supported by this service.
       */
      private final Set notificationTypes = new HashSet();
  
      /**
       * A dynamic proxy to the dependency service.
       */
      private DependencyServiceMBean dependencyService;
  
      /**
       * A dynamic proxy to the relation service.
       */
      private RelationServiceMBean relationService;
  
      /**
       * The sequence number of the events.
       */
      private long sequenceNumber;
  
      /**
       * The time this application started.
       */
      private long startTime;
  
      // This must be volatile otherwise getState must be synchronized which will result in
deadlock as dependent
      // objects check if each other are in one state or another (i.e., classic A calls B
while B calls A)
      private volatile State state = State.STOPPED;
  
      /**
       * Check if component can start.  Dependencies in the dependency service have already
been
       * checked at this point.
       *
       * Note: this method is called from within a synchronized block, so be careful what
you call as you
       * may create a deadlock.
       *
       * @return true if the component can start; otherwise false
       */
      protected boolean canStart() {
          return true;
      }
  
      /**
       * Do the start tasks for the component.  Called in the STARTING state by
       * the start() and startRecursive() methods to perform the tasks required to
       * start the component.
       *
       * Note: this method is called from within a synchronized block, so be careful what
you call as you
       * may create a deadlock.
       *
       * @throws Exception
       */
      protected void doStart() throws Exception {
      }
  
      /**
       * Check if component can stop.  Dependencies in the dependency service have already
been
       * checked at this point.
       *
       * Note: this method is called from within a synchronized block, so be careful what
you call as you
       * may create a deadlock.
       *
       * @return true if the component can stop; otherwise false
       */
      protected boolean canStop() {
          return true;
      }
  
      /**
       * Do the stop tasks for the component.  Called in the STOPPING state by the stop()
       * method to perform the tasks required to stop the component.
       *
       * Note: this method is called from within a synchronized block, so be careful what
you call as you
       * may create a deadlock.
       *
       * @throws Exception
       */
      protected void doStop() throws Exception {
      }
  
      public ObjectName preRegister(MBeanServer server, ObjectName objectName) throws Exception
{
          this.server = server;
          this.objectName = objectName;
          dependencyService = JMXUtil.getDependencyService(server);
          relationService = JMXUtil.getRelationService(server);
  
          NotificationFilterSupport mbeanServerFilter = new NotificationFilterSupport();
          mbeanServerFilter.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);
          mbeanServerFilter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
          server.addNotificationListener(JMXUtil.DELEGATE_NAME, this, mbeanServerFilter, null);
  
          NotificationFilterSupport relationServiceFilter = new NotificationFilterSupport();
          relationServiceFilter.enableType(RelationNotification.RELATION_BASIC_REMOVAL);
          relationServiceFilter.enableType(RelationNotification.RELATION_MBEAN_REMOVAL);
          server.addNotificationListener(JMXUtil.RELATION_SERVICE_NAME, this, relationServiceFilter,
null);
  
          return objectName;
      }
  
      public void postRegister(Boolean ignored) {
      }
  
      public void preDeregister() throws Exception {
      }
  
      public void postDeregister() {
      }
  
      public final String getObjectName() {
          return objectName.toString();
      }
  
      public final boolean isStateManageable() {
          return true;
      }
  
      public boolean isStatisticsProvider() {
          return false;
      }
  
      public final boolean isEventProvider() {
          return true;
      }
  
      public final String[] getEventTypes() {
          return (String[])notificationTypes.toArray(new String[notificationTypes.size()]);
      }
  
      public MBeanNotificationInfo[] getNotificationInfo() {
          return new MBeanNotificationInfo[]{
              new MBeanNotificationInfo(
                      getEventTypes(),
                      "javax.management.Notification",
                      "J2EE Notifications")
          };
      }
  
      protected void addEventType(String eventType) {
          notificationTypes.add(eventType);
      }
  
      /**
       * Sends the specified MBean notification.
       *
       * Note:  This method can not be call while the current thread holds a syncronized lock
on this MBean,
       * because this method sends JMX notifications.  Sending a general notification from
a synchronized block
       * is a bad idea and therefore not allowed.
       *
       * @param type the notification type to send
       */
      private final void doNotification(String type) {
          assert !Thread.holdsLock(this): "This method cannot be called while holding a syncrhonized
lock on this";
          sendNotification(new Notification(type, this, sequenceNumber++));
      }
  
      public synchronized final long getStartTime() {
          return startTime;
      }
  
      /**
       * Moves this MBean to the STARTING state and then attempst to move this MBean immedately
to the STARTED
       * state.
       *
       * Note:  This method cannot be call while the current thread holds a syncronized lock
on this MBean,
       * because this method sends JMX notifications.  Sending a general notification from
a synchronized block
       * is a bad idea and therefore not allowed.
       *
       * @throws Exception  If an exception occurs while starting this MBean
       */
      public final void start() throws Exception {
          assert !Thread.holdsLock(this): "This method cannot be called while holding a syncrhonized
lock on this";
  
          // Move to the starting state
          synchronized (this) {
              State state = getStateInstance();
              if (state == State.STARTING || state == State.RUNNING) {
                  return;
              }
              setStateInstance(State.STARTING);
          }
          doNotification(State.STARTING.getEventTypeValue());
  
          State newState = null;
          try {
              synchronized (this) {
                  try {
                      // if we are still trying to start and can start now... start
                      if(getStateInstance() == State.STARTING &&
                              dependencyService.canStart(objectName) && canStart())
{
                          enrollInRelationships();
                          doStart();
                          setStateInstance(State.RUNNING);
                          newState = State.RUNNING;
                      }
                  } catch (Exception e) {
                      setStateInstance(State.FAILED);
                      newState = State.FAILED;
                      throw e;
                  } catch (Error e) {
                      setStateInstance(State.FAILED);
                      newState = State.FAILED;
                      throw e;
                  }
              }
          } finally {
              if(newState != null) {
                  doNotification(newState.getEventTypeValue());
              }
          }
      }
  
      /**
       * Moves this MBean to the STOPPING state, calls stop on all start dependent children,
and then attempt
       * to move this MBean to the STOPPED state.
       *
       * Note:  This method can not be call while the current thread holds a syncronized lock
on this MBean,
       * because this method sends JMX notifications.  Sending a general notification from
a synchronized block
       * is a bad idea and therefore not allowed.
       *
       * @throws Exception  If an exception occurs while stoping this MBean or any of the
childern
       */
      public final void stop() throws Exception {
          assert !Thread.holdsLock(this): "This method cannot be called while holding a syncrhonized
lock on this";
  
          // move to the stopping state
          synchronized (this) {
              State state = getStateInstance();
              if (state == State.STOPPED || state == State.STOPPING) {
                  return;
              }
              setStateInstance(State.STOPPING);
          }
          doNotification(State.STOPPING.getEventTypeValue());
  
          // Don't try to stop dependents from within a synchronized block... this should
reduce deadlocks
  
          // stop all of my dependent objects
          Set dependents = dependencyService.getStartChildren(objectName);
          for (Iterator iterator = dependents.iterator(); iterator.hasNext();) {
              ObjectName name = (ObjectName) iterator.next();
              try {
                  server.invoke(name, "stop", null, null);
              } catch (ReflectionException e) {
                  if (e.getTargetException() instanceof NoSuchMethodException) {
                      // did not have a stop method - ok
                  } else {
                      throw e;
                  }
              }
          }
  
          // Try to fully stop
          State newState = null;
          try {
              synchronized (this) {
                  // if we are still trying to stop...
                  if (getStateInstance() == State.STOPPING) {
                      try {
                          // if we can stop, stop
                          if (dependencyService.canStop(objectName) && canStop())
{
                              unenrollInRelationships();
                              doStop();
                              setStateInstance(State.STOPPED);
                              newState = State.STOPPED;
                          }
                      } catch (Exception e) {
                          setStateInstance(State.FAILED);
                          newState = State.FAILED;
                          throw e;
                      } catch (Error e) {
                          setStateInstance(State.FAILED);
                          newState = State.FAILED;
                          throw e;
                      }
                  }
              }
          } finally {
              if(newState != null) {
                  doNotification(newState.getEventTypeValue());
              }
          }
      }
  
      /**
       * Starts this MBean and then attempts to start all of the start dependent children
of this MBean.
       *
       * Note:  This method can not be call while the current thread holds a syncronized lock
on this MBean,
       * because this method sends JMX notifications.  Sending a general notification from
a synchronized block
       * is a bad idea and therefore not allowed.
       *
       * @throws Exception  if a problem occurs will starting this MBean or any child MBean
       */
      public final void startRecursive() throws Exception {
          assert !Thread.holdsLock(this): "This method cannot be called while holding a syncrhonized
lock on this";
  
          State state = getStateInstance();
          if (state != State.STOPPED && state != State.FAILED) {
              // Cannot startRecursive while in the stopping state
              // Dain: I don't think we can throw an exception here because there is no way
for the caller
              // to lock the instance and check the state before calling
              return;
          }
  
          // get myself starting
          start();
  
          // startRecursive all of objects that depend on me
          Set dependents = dependencyService.getStartChildren(objectName);
          for (Iterator iterator = dependents.iterator(); iterator.hasNext();) {
              ObjectName dependent = (ObjectName) iterator.next();
              try {
                  server.invoke(dependent, "startRecursive", null, null);
              } catch (ReflectionException e) {
                  if (e.getTargetException() instanceof NoSuchMethodException) {
                      // did not have a startRecursive method - ok
                  } else {
                      throw e;
                  }
              }
          }
      }
  
      public void handleNotification(Notification n, Object o) {
          String type = n.getType();
          ObjectName source = null;
          if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) {
              MBeanServerNotification notification = (MBeanServerNotification) n;
              source = notification.getMBeanName();
              try {
                  server.addNotificationListener(source, this, NotificationType.NOTIFICATION_FILTER,
null);
              } catch (InstanceNotFoundException e) {
                  // the instance died before we could get going... not a big deal
                  return;
              }
          } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type)) {
              MBeanServerNotification notification = (MBeanServerNotification) n;
              source = notification.getMBeanName();
          } else if (RelationNotification.RELATION_BASIC_REMOVAL.equals(type) ||
                  RelationNotification.RELATION_MBEAN_REMOVAL.equals(type)) {
  
              if(getStateInstance() == State.RUNNING) {
                  RelationNotification notification = (RelationNotification) n;
                  String relationType = notification.getRelationTypeName();
                  if(relationType != null) {
                      Set relationships = dependencyService.getRelationships(objectName);
                      for (Iterator i = relationships.iterator(); i.hasNext();) {
                          MBeanRelationship relationship = (MBeanRelationship) i.next();
                          if(relationType.equals(relationship.getType())){
                              checkState();
                              return;
                          }
                      }
                  }
              }
              return;
          } else {
              source = (ObjectName) n.getSource();
          }
          Set dependencies = dependencyService.getStartParents(objectName);
          if (dependencies.contains(source)) {
              checkState();
          }
      }
  
      public final int getState() {
          return state.toInt();
      }
  
      public final State getStateInstance() {
          return state;
      }
  
      /**
       * Set the Component state.
       * @param newState the target state to transition
       * @throws IllegalStateException Thrown if the transition is not supported by the J2EE
Management lifecycle.
       */
      private synchronized void setStateInstance(State newState) throws IllegalStateException
{
          switch (state.toInt()) {
          case State.STOPPED_INDEX:
              switch (newState.toInt()) {
              case State.STARTING_INDEX:
                  break;
              case State.STOPPED_INDEX:
              case State.RUNNING_INDEX:
              case State.STOPPING_INDEX:
              case State.FAILED_INDEX:
                  throw new IllegalStateException(
                          "Can not transition to " + newState + " state from " + state);
              }
              break;
  
          case State.STARTING_INDEX:
              switch (newState.toInt()) {
              case State.RUNNING_INDEX:
              case State.FAILED_INDEX:
              case State.STOPPING_INDEX:
                  break;
              case State.STOPPED_INDEX:
              case State.STARTING_INDEX:
                  throw new IllegalStateException(
                          "Can not transition to " + newState + " state from " + state);
              }
              break;
  
          case State.RUNNING_INDEX:
              switch (newState.toInt()) {
              case State.STOPPING_INDEX:
              case State.FAILED_INDEX:
                  break;
              case State.STOPPED_INDEX:
              case State.STARTING_INDEX:
              case State.RUNNING_INDEX:
                  throw new IllegalStateException(
                          "Can not transition to " + newState + " state from " + state);
  
              }
              break;
  
          case State.STOPPING_INDEX:
              switch (newState.toInt()) {
              case State.STOPPED_INDEX:
              case State.FAILED_INDEX:
                  break;
              case State.STARTING_INDEX:
              case State.RUNNING_INDEX:
              case State.STOPPING_INDEX:
                  throw new IllegalStateException(
                          "Can not transition to " + newState + " state from " + state);
              }
              break;
  
          case State.FAILED_INDEX:
              switch (newState.toInt()) {
              case State.STARTING_INDEX:
              case State.STOPPING_INDEX:
                  break;
              case State.RUNNING_INDEX:
              case State.STOPPED_INDEX:
              case State.FAILED_INDEX:
                  throw new IllegalStateException(
                          "Can not transition to " + newState + " state from " + state);
              }
              break;
          }
          log.debug(objectName.toString() + " State changed from " + state + " to " + newState);
          if (newState == State.RUNNING) {
              startTime = System.currentTimeMillis();
          }
          state = newState;
      }
  
      /**
       * Checks if we need to make a state transition based on our dependencies registered
with the dependency service.
       *
       * Note: Do not call this from within a synchronized block as it makes may send a JMX
notification
       */
      protected void checkState() {
          assert !Thread.holdsLock(this): "This method cannot be called while holding a syncrhonized
lock on this";
  
          State newState = null;
          try {
              synchronized (this) {
                  State state = getStateInstance();
                  if (state == State.STARTING) {
                      if (dependencyService.canStart(objectName) && canStart()) {
                          try {
                              doStart();
                              setStateInstance(State.RUNNING);
                              newState = State.RUNNING;
                          } catch (Exception e) {
                              setStateInstance(State.FAILED);
                              newState = State.FAILED;
                          } catch (Error e) {
                              setStateInstance(State.FAILED);
                              newState = State.FAILED;
                          }
                      }
                  } else if (state == State.RUNNING) {
                      // Someone stopping, stopped, failed or unregistered we need to change
state
                      State recommendState = dependencyService.shouldChangeState(objectName);
                      if (recommendState != null) {
                          setStateInstance(recommendState);
                          newState = recommendState;
                      }
                  } else if (state == State.STOPPING) {
                      if (dependencyService.canStop(objectName) && canStop()) {
                          try {
                              unenrollInRelationships();
                              doStop();
                              setStateInstance(State.STOPPED);
                              newState = State.STOPPED;
                          } catch (Exception e) {
                              setStateInstance(State.FAILED);
                              newState = State.FAILED;
                          } catch (Error e) {
                              setStateInstance(State.FAILED);
                              newState = State.FAILED;
                          }
                      }
                  }
              }
          } finally {
              if (newState != null) {
                  doNotification(newState.getEventTypeValue());
              }
          }
      }
  
      /**
       * Enrolls this MBean is all relationships specified in the dependency service.
       *
       * @throws StartException is this MBean can not be enrolled in a relationship
       */
      private synchronized final void enrollInRelationships() throws StartException {
          String relationshipType = null;
          String relationshipRole = null;
          String targetRoleName = null;
          try {
              Set relationships = dependencyService.getRelationships(objectName);
              for (Iterator i = relationships.iterator(); i.hasNext();) {
                  MBeanRelationship relationship = (MBeanRelationship) i.next();
  
                  // if we don't have a relationship instance create one
                  String relationshipName = relationship.getName();
                  relationshipRole = relationship.getRole();
                  if (!relationService.hasRelation(relationshipName).booleanValue()) {
                      relationshipType = relationship.getType();
                      RoleList roleList = new RoleList();
                      roleList.add(new Role(relationshipRole, Collections.singletonList(objectName)));
  
                      // if we have a target we need to add it to the role list
                      ObjectName target = relationship.getTarget();
                      if (target != null) {
                          targetRoleName = relationship.getTargetRole();
                          if (targetRoleName == null || targetRoleName.length() == 0) {
                              List roles = relationService.getRoleInfos(relationshipType);
                              if (roles.size() < 2) {
                                  throw new StartException("Relationship has less than two
roles. You cannot specify a target");
                              }
                              if (roles.size() > 2) {
                                  throw new StartException("Relationship has more than two
roles. You must use targetRoleName");
                              }
                              if (((RoleInfo) roles.get(0)).getName().equals(relationshipRole))
{
                                  targetRoleName = ((RoleInfo) roles.get(1)).getName();
                              } else {
                                  targetRoleName = ((RoleInfo) roles.get(0)).getName();
                              }
                              relationship.setTargetRole(targetRoleName);
                          }
  
                          roleList.add(new Role(targetRoleName, Collections.singletonList(target)));
                      }
                      relationService.createRelation(relationshipName, relationshipType, roleList);
                      relationship.setCreatedRelationship(true);
                  } else {
                      // We have an exiting relationship -- just add to the existing role
                      List members = relationService.getRole(relationshipName, relationshipRole);
                      if (!members.contains(objectName)) {
                          members.add(objectName);
                          relationService.setRole(relationshipName, new Role(relationshipRole,
members));
                      }
                      relationship.setCreatedRelationship(false);
                  }
              }
          } catch (RelationTypeNotFoundException e) {
              throw new StartException("Relationship type is not registered: relationType="
+ relationshipType);
          } catch (RelationServiceNotRegisteredException e) {
              throw new StartException("RelationshipService is not registered", e);
          } catch (RoleNotFoundException e) {
              throw new StartException("RelationshipService is not registered", e);
          } catch (InvalidRelationIdException e) {
              throw new StartException("Relationship type does not contain role:" +
                      " relationType=" + relationshipType +
                      " sourceRole=" + relationshipRole +
                      " targetRole=" + targetRoleName, e);
          } catch (InvalidRoleValueException e) {
              throw new StartException("Relationship role state is invalid", e);
          } catch (RelationNotFoundException e) {
              throw new StartException("Relation was unregistered while executing", e);
          }
      }
  
      /**
       * Removes this MBean from all relationships specified in the dependency service.
       *
       * @throws StopException is this MBean can not be removed in a relationship
       */
      private synchronized final void unenrollInRelationships() throws StopException {
          String relationshipType = null;
          String relationshipRole = null;
          try {
              Set relationships = dependencyService.getRelationships(objectName);
              for (Iterator i = relationships.iterator(); i.hasNext();) {
                  MBeanRelationship relationship = (MBeanRelationship) i.next();
                  String relationshipName = relationship.getName();
                  if(relationship.getCreatedRelationship()) {
                      // drop the entire relationship
                      relationService.removeRelation(relationshipName);
                  } else {
                      // just remove myself from the relationship
                      relationshipRole = relationship.getRole();
                      List members = relationService.getRole(relationshipName, relationshipRole);
                      if (members.contains(objectName)) {
                          members.remove(objectName);
                          relationService.setRole(relationshipName, new Role(relationshipRole,
members));
                      }
                  }
              }
          } catch (RelationTypeNotFoundException e) {
              throw new StopException("Relationship type is not registered: relationType="
+ relationshipType);
          } catch (RelationServiceNotRegisteredException e) {
              throw new StopException("RelationshipService is not registered", e);
          } catch (RoleNotFoundException e) {
              throw new StopException("RelationshipService is not registered", e);
          } catch (InvalidRoleValueException e) {
              throw new StopException("Relationship role state is invalid", e);
          } catch (RelationNotFoundException e) {
              throw new StopException("Relation was unregistered while executing", e);
          }
      }
  
      public String toString() {
          return objectName.toString();
      }
  }
  
  
  

Mime
View raw message