/**
   * This method sets the node(s) to publish or unpublish on the supplied publishing details. If the
   * actionedUponNode is a folder then it will include all content nodes within that folder.
   *
   * @param actionedUponNodeRef
   * @param unpublish
   * @param details
   */
  private List<NodeRef> setNodes(
      NodeRef actionedUponNodeRef, boolean unpublish, PublishingDetails details) {
    List<NodeRef> nodes = new ArrayList<NodeRef>();
    QName nodeType = nodeService.getType(actionedUponNodeRef);
    if (dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER)) {
      List<ChildAssociationRef> children = nodeService.getChildAssocs(actionedUponNodeRef);
      for (ChildAssociationRef childRef : children) {
        NodeRef child = childRef.getChildRef();
        if (dictionaryService.isSubClass(nodeService.getType(child), ContentModel.TYPE_CONTENT)) {
          nodes.add(child);
        }
      }
    } else {
      nodes.add(actionedUponNodeRef);
    }

    if (unpublish) {
      details.addNodesToUnpublish(nodes);
    } else {
      details.addNodesToPublish(nodes);
    }
    return nodes;
  }
  @SuppressWarnings("unchecked")
  @Override
  protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
    Boolean isUnpublish = (Boolean) action.getParameterValue(PARAM_UNPUBLISH);
    boolean unpublish = ((isUnpublish != null) && isUnpublish);
    String publishChannelId = (String) action.getParameterValue(PARAM_PUBLISH_CHANNEL_ID);
    String publishChannelName = (String) action.getParameterValue(PARAM_PUBLISH_CHANNEL_NAME);
    String statusUpdate = (String) action.getParameterValue(PARAM_STATUS_UPDATE);
    List<String> statusUpdateChannelNames =
        buildStringList(action.getParameterValue(PARAM_STATUS_UPDATE_CHANNEL_NAMES));
    List<String> statusUpdateChannelIds =
        buildStringList(action.getParameterValue(PARAM_STATUS_UPDATE_CHANNEL_IDS));
    Boolean includeLinkInStatusUpdate =
        (Boolean) action.getParameterValue(PARAM_INCLUDE_LINK_IN_STATUS_UPDATE);
    boolean appendLink = ((includeLinkInStatusUpdate == null) || includeLinkInStatusUpdate);
    Date scheduledTime = (Date) action.getParameterValue(PARAM_SCHEDULED_TIME);
    String comment = (String) action.getParameterValue(PARAM_COMMENT);

    Channel publishChannel =
        publishChannelId == null
            ? channelService.getChannelByName(publishChannelName)
            : channelService.getChannelById(publishChannelId);
    if (publishChannel != null) {
      PublishingDetails details = publishingService.createPublishingDetails();
      details.setPublishChannelId(publishChannel.getId());
      List<NodeRef> nodes = setNodes(actionedUponNodeRef, unpublish, details);
      if (statusUpdateChannelNames != null) {
        for (String statusUpdateChannelName : statusUpdateChannelNames) {
          Channel statusUpdateChannel = channelService.getChannelByName(statusUpdateChannelName);
          if (statusUpdateChannel != null) {
            details.addStatusUpdateChannels(statusUpdateChannel.getId());
          }
        }
      }
      if (statusUpdateChannelIds != null) {
        for (String statusUpdateChannelId : statusUpdateChannelIds) {
          Channel statusUpdateChannel = channelService.getChannelById(statusUpdateChannelId);
          if (statusUpdateChannel != null) {
            details.addStatusUpdateChannels(statusUpdateChannel.getId());
          }
        }
      }
      if (!unpublish && !details.getStatusUpdateChannels().isEmpty()) {
        details.setStatusMessage(statusUpdate);
        if (appendLink) {
          NodeRef nodeToLinkTo =
              (NodeRef) action.getParameterValue(PARAM_NODE_TO_LINK_STATUS_UPDATE_TO);
          if (nodeToLinkTo == null) {
            // No node has been specified explicitly as being the one to link to
            // We'll make an assumption if only one node is being published...
            if (nodes.size() == 1) {
              nodeToLinkTo = nodes.get(0);
            }
          }
          if ((nodeToLinkTo != null) && nodes.contains(nodeToLinkTo)) {
            details.setStatusNodeToLinkTo(nodeToLinkTo);
          }
        }
      }
      if (scheduledTime != null) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(scheduledTime);
        details.setSchedule(cal);
      }
      details.setComment(comment);
      publishingService.scheduleNewEvent(details);
    } else {
      throw new AlfrescoRuntimeException(
          MSG_CHANNEL_NOT_FOUND,
          new Object[] {publishChannelId == null ? publishChannelName : publishChannelId});
    }
  }