private void addContributeeActionsIfAny(
      final ObjectAdapter serviceAdapter, final List<ObjectAction> contributeeActionsToAppendTo) {
    final ObjectSpecification specification = serviceAdapter.getSpecification();
    if (specification == this) {
      return;
    }
    final List<ObjectAction> contributeeActions = Lists.newArrayList();
    final List<ObjectAction> serviceActions =
        specification.getObjectActions(
            ActionType.ALL, Contributed.INCLUDED, Filters.<ObjectAction>any());
    for (final ObjectAction serviceAction : serviceActions) {
      if (isAlwaysHidden(serviceAction)) {
        continue;
      }
      final NotContributedFacet notContributed = serviceAction.getFacet(NotContributedFacet.class);
      if (notContributed != null && notContributed.toActions()) {
        continue;
      }
      if (!(serviceAction instanceof ObjectActionImpl)) {
        continue;
      }
      final ObjectActionImpl contributedAction = (ObjectActionImpl) serviceAction;

      // see if qualifies by inspecting all parameters
      final int contributeeParam = contributeeParameterMatchOf(contributedAction);
      if (contributeeParam != -1) {
        ObjectActionContributee contributeeAction =
            new ObjectActionContributee(
                serviceAdapter, contributedAction, contributeeParam, this, objectMemberContext);
        facetProcessor.processMemberOrder(metadataProperties, contributeeAction);
        contributeeActions.add(contributeeAction);
      }
    }
    contributeeActionsToAppendTo.addAll(contributeeActions);
  }
 /**
  * Determines if this class represents the same class, or a subclass, of the specified class.
  *
  * <p>cf {@link Class#isAssignableFrom(Class)}, though target and parameter are the opposite way
  * around, ie:
  *
  * <pre>
  * cls1.isAssignableFrom(cls2);
  * </pre>
  *
  * <p>is equivalent to:
  *
  * <pre>
  * spec2.isOfType(spec1);
  * </pre>
  *
  * <p>Callable after {@link #introspectTypeHierarchyAndMembers()} has been called.
  */
 @Override
 public boolean isOfType(final ObjectSpecification specification) {
   // do the comparison using value types because of a possible aliasing/race condition
   // in matchesParameterOf when building up contributed associations
   if (specification.getSpecId().equals(this.getSpecId())) {
     return true;
   }
   for (final ObjectSpecification interfaceSpec : interfaces()) {
     if (interfaceSpec.isOfType(specification)) {
       return true;
     }
   }
   final ObjectSpecification superclassSpec = superclass();
   return superclassSpec != null ? superclassSpec.isOfType(specification) : false;
 }
 private void addIfReturnsSubtype(
     final ObjectAction serviceAction, final List<ObjectAction> matchingActionsToAppendTo) {
   final ObjectSpecification returnType = serviceAction.getReturnType();
   if (returnType == null) {
     return;
   }
   if (returnType.isParentedOrFreeCollection()) {
     final TypeOfFacet facet = serviceAction.getFacet(TypeOfFacet.class);
     if (facet != null) {
       final ObjectSpecification elementType = facet.valueSpec();
       addIfReturnsSubtype(serviceAction, elementType, matchingActionsToAppendTo);
     }
   } else {
     addIfReturnsSubtype(serviceAction, returnType, matchingActionsToAppendTo);
   }
 }
  /**
   * Erstellt ein neues KExDavObject
   *
   * @param objectSpecification Objekt-Spezifikation
   * @param connection Datenverteiler-Verbindung
   * @param manager KExDaV-Manager-Objekt, an das Benachrichtigungen gesendet werden können
   */
  public KExDaVObject(
      final ObjectSpecification objectSpecification,
      final ClientDavInterface connection,
      final ManagerInterface manager) {
    _manager = manager;
    if (objectSpecification == null)
      throw new IllegalArgumentException("objectSpecification ist null");
    if (connection == null) throw new IllegalArgumentException("connection ist null");

    _objectSpecification = objectSpecification;
    _connection = connection;

    final SystemObject object = objectSpecification.getObject(_connection.getDataModel());
    setWrappedObject(object);

    // Anmeldung auf Erstellung/Löschung des Objektes (nicht nötig bei schon vorhandenen
    // Konfigurationsobjekten)
    if (object == null || object.getType() instanceof DynamicObjectType) {
      /**
       * Direkt beim typ.dynamischesObject anmelden. Das Anmelden beim eigentlichen Typ dieses
       * Objektes funktioniert nicht immer zuverlässig, weil unter Umständen dieses Objekt noch gar
       * nicht vorhanden und deshalb kein Typ ermittelbar ist, oder weil evtl. jemand das Objekt mit
       * diesem Typ löschen könnte und ein anderes Objekt mit der gleichen Pid von einem anderen Typ
       * erstellen könnte
       */
      final DynamicObjectType dynamicObjectType =
          (DynamicObjectType) connection.getDataModel().getType(Constants.Pids.TypeDynamicObject);
      if (dynamicObjectType == null)
        throw new IllegalStateException(
            Constants.Pids.TypeDynamicObject + " konnte nicht gefunden werden");
      final Listener objectCreateDeleteListener = new Listener();
      dynamicObjectType.addInvalidationListener(objectCreateDeleteListener);
      dynamicObjectType.addObjectCreationListener(objectCreateDeleteListener);
    }
  }
 private void addIfReturnsSubtype(
     final ObjectAction serviceAction,
     final ObjectSpecification actionType,
     final List<ObjectAction> matchingActionsToAppendTo) {
   if (actionType.isOfType(this)) {
     matchingActionsToAppendTo.add(serviceAction);
   }
 }
  @Override
  public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    final KExDaVObject other = (KExDaVObject) o;

    if (!_objectSpecification.equals(other._objectSpecification)) return false;

    return true;
  }
 @Override
 public <Q extends Facet> Q getFacet(final Class<Q> facetType) {
   final Q facet = super.getFacet(facetType);
   Q noopFacet = null;
   if (isNotANoopFacet(facet)) {
     return facet;
   } else {
     noopFacet = facet;
   }
   if (interfaces() != null) {
     final List<ObjectSpecification> interfaces = interfaces();
     for (int i = 0; i < interfaces.size(); i++) {
       final ObjectSpecification interfaceSpec = interfaces.get(i);
       if (interfaceSpec == null) {
         // HACK: shouldn't happen, but occurring on occasion when
         // running
         // XATs under JUnit4. Some sort of race condition?
         continue;
       }
       final Q interfaceFacet = interfaceSpec.getFacet(facetType);
       if (isNotANoopFacet(interfaceFacet)) {
         return interfaceFacet;
       } else {
         if (noopFacet == null) {
           noopFacet = interfaceFacet;
         }
       }
     }
   }
   // search up the inheritance hierarchy
   final ObjectSpecification superSpec = superclass();
   if (superSpec != null) {
     final Q superClassFacet = superSpec.getFacet(facetType);
     if (isNotANoopFacet(superClassFacet)) {
       return superClassFacet;
     }
   }
   return noopFacet;
 }
  /**
   * Synthesises {@link ObjectAssociation}s from matching {@link ObjectAction}s of any of the
   * services that accept one parameter
   */
  private List<ObjectAssociation> createContributeeAssociations(
      final ObjectAdapter serviceAdapter) {

    final ObjectSpecification specification = serviceAdapter.getSpecification();
    final List<ObjectAction> serviceActions =
        specification.getObjectActions(
            ActionType.USER, Contributed.INCLUDED, Filters.<ObjectAction>any());

    final List<ObjectActionImpl> contributedActions = Lists.newArrayList();
    for (final ObjectAction serviceAction : serviceActions) {
      if (isAlwaysHidden(serviceAction)) {
        continue;
      }
      final NotContributedFacet notContributed = serviceAction.getFacet(NotContributedFacet.class);
      if (notContributed != null && notContributed.toAssociations()) {
        continue;
      }
      if (!serviceAction.hasReturn()) {
        continue;
      }
      if (serviceAction.getParameterCount() != 1
          || contributeeParameterMatchOf(serviceAction) == -1) {
        continue;
      }
      if (!(serviceAction instanceof ObjectActionImpl)) {
        continue;
      }
      if (!serviceAction.getSemantics().isSafeInNature()) {
        continue;
      }
      contributedActions.add((ObjectActionImpl) serviceAction);
    }

    return Lists.newArrayList(
        Iterables.transform(
            contributedActions, createContributeeAssociationFunctor(serviceAdapter, this)));
  }
 @Override
 public int hashCode() {
   return _objectSpecification.hashCode();
 }
 @Override
 public String toString() {
   final SystemObject wrappedObject = getWrappedObject();
   if (wrappedObject != null) return wrappedObject.getPidOrNameOrId();
   return _objectSpecification.toString();
 }