gt:             if (!publicationTrees.isEmpty()) {
context: /*
   * (C) Copyright 2007-2013 Nuxeo SA (http://nuxeo.com/) and contributors.
   *
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the GNU Lesser General Public License
   * (LGPL) version 2.1 which accompanies this distribution, and is available at
   * http://www.gnu.org/licenses/lgpl-2.1.html
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * Contributors:
   *     Narcis Paslaru
   *     Florent Guillaume
   *     Thierry Martins
   *     Thomas Roger
   */
  
  package org.nuxeo.ecm.platform.publisher.web;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import javax.faces.context.FacesContext;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.Factory;
  import org.jboss.seam.annotations.In;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Observer;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.intercept.BypassInterceptors;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Events;
  import org.jboss.seam.faces.FacesMessages;
  import org.jboss.seam.international.StatusMessage;
  import org.nuxeo.ecm.core.api.ClientException;
  import org.nuxeo.ecm.core.api.CoreSession;
  import org.nuxeo.ecm.core.api.DocumentModel;
  import org.nuxeo.ecm.core.api.DocumentRef;
  import org.nuxeo.ecm.core.api.IdRef;
  import org.nuxeo.ecm.core.api.PathRef;
  import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner;
  import org.nuxeo.ecm.core.api.event.CoreEventConstants;
  import org.nuxeo.ecm.core.api.event.DocumentEventCategories;
  import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl;
  import org.nuxeo.ecm.core.api.security.SecurityConstants;
  import org.nuxeo.ecm.core.event.Event;
  import org.nuxeo.ecm.core.event.EventProducer;
  import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
  import org.nuxeo.ecm.core.schema.FacetNames;
  import org.nuxeo.ecm.core.schema.SchemaManager;
  import org.nuxeo.ecm.platform.publisher.api.PublicationNode;
  import org.nuxeo.ecm.platform.publisher.api.PublicationTree;
  import org.nuxeo.ecm.platform.publisher.api.PublicationTreeNotAvailable;
  import org.nuxeo.ecm.platform.publisher.api.PublishedDocument;
  import org.nuxeo.ecm.platform.publisher.api.PublisherException;
  import org.nuxeo.ecm.platform.publisher.api.PublisherService;
  import org.nuxeo.ecm.platform.publisher.api.PublishingEvent;
  import org.nuxeo.ecm.platform.ui.web.util.ComponentUtils;
  import org.nuxeo.ecm.webapp.documentsLists.DocumentsListsManager;
  import org.nuxeo.ecm.webapp.helpers.EventManager;
  import org.nuxeo.ecm.webapp.helpers.EventNames;
  import org.nuxeo.runtime.api.Framework;
  
  /**
   * This Seam bean manages the publishing tab.
   *
   * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
   */
  @Name("publishActions")
  @Scope(ScopeType.CONVERSATION)
  public class PublishActionsBean extends AbstractPublishActions implements
          Serializable {
  
      public static class PublicationTreeInformation {
  
          private final String name;
  
          private final String title;
  
          public PublicationTreeInformation(String treeName, String treeTitle) {
              this.name = treeName;
              this.title = treeTitle;
          }
  
          public String getName() {
              return name;
          }
  
          public String getTitle() {
              return title;
          }
      }
  
      private static final long serialVersionUID = 1L;
  
      private static final Log log = LogFactory.getLog(PublishActionsBean.class);
  
      @In(create = true)
      protected transient DocumentsListsManager documentsListsManager;
  
      @In(create = true, required = false)
      protected transient FacesMessages facesMessages;
  
      protected transient PublisherService publisherService;
  
      protected String currentPublicationTreeNameForPublishing;
  
      protected PublicationTree currentPublicationTree;
  
      protected String publishingComment;
  
      protected static Set<String> sectionTypes;
  
      protected Map<String, String> publicationParameters = new HashMap<>();
  
      protected String treeSID;
  
      @Create
      public void create() {
          try {
              publisherService = Framework.getService(PublisherService.class);
          } catch (Exception e) {
              throw new IllegalStateException("Publisher service not deployed.",
                      e);
          }
      }
  
      @Destroy
      public void destroy() {
          if (currentPublicationTree != null) {
              currentPublicationTree.release();
              currentPublicationTree = null;
          }
          if (treeSID != null) {
              publisherService.releaseAllTrees(treeSID);
          }
      }
  
      protected Map<String, String> filterEmptyTrees(Map<String, String> trees)
              throws PublicationTreeNotAvailable, ClientException {
  
          Map<String, String> filteredTrees = new HashMap<>();
  
          List<String> prefilteredTrees = filterEmptyTrees(trees.keySet());
  
          for (String ptree : prefilteredTrees) {
              filteredTrees.put(ptree, trees.get(ptree));
          }
  
          return filteredTrees;
      }
  
      protected List<String> filterEmptyTrees(Collection<String> trees)
              throws PublicationTreeNotAvailable, ClientException {
          List<String> filteredTrees = new ArrayList<>();
  
          for (String tree : trees) {
              try {
                  PublicationTree pTree = publisherService.getPublicationTree(
                          tree, documentManager, null,
                          navigationContext.getCurrentDocument());
                  if (pTree != null) {
                      if (pTree.getTreeType().equals(
                              "RootSectionsPublicationTree")) {
                          if (pTree.getChildrenNodes().size() > 0) {
                              filteredTrees.add(tree);
                          }
                      } else {
                          filteredTrees.add(tree);
                      }
                  }
              } catch (PublicationTreeNotAvailable e) {
                  log.warn("Publication tree " + tree
                          + " is not available : check config");
                  log.debug("Publication tree " + tree
                          + " is not available : root cause is ", e);
              }
          }
          return filteredTrees;
      }
  
      @Factory(value = "availablePublicationTrees", scope = ScopeType.EVENT)
      public List<PublicationTreeInformation> getAvailablePublicationTrees()
              throws ClientException {
          Map<String, String> trees = publisherService.getAvailablePublicationTrees();
          // remove empty trees
          trees = filterEmptyTrees(trees);
          List<PublicationTreeInformation> treesInformation = new ArrayList<>();
          for (Map.Entry<String, String> entry : trees.entrySet()) {
              treesInformation.add(new PublicationTreeInformation(entry.getKey(),
                      entry.getValue()));
          }
          return treesInformation;
      }
  
      public String doPublish(PublicationNode publicationNode)
              throws ClientException {
          PublicationTree tree = getCurrentPublicationTreeForPublishing();
          return doPublish(tree, publicationNode);
      }
  
      public String doPublish(PublicationTree tree,
              PublicationNode publicationNode) throws ClientException {
          if (tree == null) {
              return null;
          }
  
          DocumentModel currentDocument = navigationContext.getCurrentDocument();
  
          PublishedDocument publishedDocument;
          try {
              publishedDocument = tree.publish(currentDocument, publicationNode,
                      publicationParameters);
          } catch (PublisherException e) {
              log.error(e, e);
              facesMessages.add(StatusMessage.Severity.ERROR,
                      messages.get(e.getMessage()));
              return null;
          }
  
          FacesContext context = FacesContext.getCurrentInstance();
          if (publishedDocument.isPending()) {
              String comment = ComponentUtils.translate(context,
                      "publishing.waiting", publicationNode.getPath(),
                      tree.getConfigName());
              // Log event on live version
              notifyEvent(PublishingEvent.documentWaitingPublication.name(),
                      null, comment, null, currentDocument);
              Events.instance().raiseEvent(
                      EventNames.DOCUMENT_SUBMITED_FOR_PUBLICATION);
              facesMessages.add(StatusMessage.Severity.INFO,
                      messages.get("document_submitted_for_publication"),
                      messages.get(currentDocument.getType()));
          } else {
              String comment = ComponentUtils.translate(context,
                      "publishing.done", publicationNode.getPath(),
                      tree.getConfigName());
              // Log event on live version
              notifyEvent(PublishingEvent.documentPublished.name(), null,
                      comment, null, currentDocument);
              Events.instance().raiseEvent(EventNames.DOCUMENT_PUBLISHED);
              // publish may checkin the document -> change
              Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
              facesMessages.add(StatusMessage.Severity.INFO,
                      messages.get("document_published"),
                      messages.get(currentDocument.getType()));
          }
          navigationContext.invalidateCurrentDocument();
          currentPublicationTree = null;
          resetCache();
          return null;
      }
  
      /**
       * @since 5.9.3
       */
      protected void resetCache() {
          Contexts.getEventContext().remove("availablePublicationTrees");
          Contexts.getEventContext().remove("publishedDocuments");
      }
  
      public void setCurrentPublicationTreeNameForPublishing(
              String currentPublicationTreeNameForPublishing)
              throws ClientException {
          this.currentPublicationTreeNameForPublishing = currentPublicationTreeNameForPublishing;
          if (currentPublicationTree != null) {
              currentPublicationTree.release();
              currentPublicationTree = null;
          }
          currentPublicationTree = getCurrentPublicationTreeForPublishing();
      }
  
      public String getCurrentPublicationTreeNameForPublishing()
              throws ClientException {
          if (currentPublicationTreeNameForPublishing == null) {
              List<String> publicationTrees = new ArrayList<>(
                      publisherService.getAvailablePublicationTree());
              publicationTrees = filterEmptyTrees(publicationTrees);
  