# GalleryRequestRouter.java

    /*
     * Copyright (C) 2000 - 2024 Silverpeas
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU Affero General Public License as
     * published by the Free Software Foundation, either version 3 of the
     * License, or (at your option) any later version.
     *
     * As a special exception to the terms and conditions of version 3.0 of
     * the GPL, you may redistribute this Program in connection with Free/Libre
     * Open Source Software ("FLOSS") applications as described in Silverpeas's
     * FLOSS exception. You should have received a copy of the text describing
     * the FLOSS exception, and it is also available here:
     * "http://www.silverpeas.org/docs/core/legal/floss_exception.html"
     *
     * This program 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 Affero General Public License for more details.
     *
     * You should have received a copy of the GNU Affero General Public License
     * along with this program. If not, see <https://www.gnu.org/licenses/>.
     */
    package org.silverpeas.components.gallery.servlets;

    import org.apache.commons.fileupload.FileItem;
    import org.silverpeas.components.gallery.ParameterNames;
    import org.silverpeas.components.gallery.constant.MediaResolution;
    import org.silverpeas.components.gallery.constant.MediaType;
    import org.silverpeas.components.gallery.control.GallerySessionController;
    import org.silverpeas.components.gallery.delegate.AbstractMediaDataDelegate;
    import org.silverpeas.components.gallery.delegate.MediaDataCreateDelegate;
    import org.silverpeas.components.gallery.delegate.MediaDataUpdateDelegate;
    import org.silverpeas.components.gallery.model.AlbumDetail;
    import org.silverpeas.components.gallery.model.Media;
    import org.silverpeas.components.gallery.model.MetaData;
    import org.silverpeas.components.gallery.model.Order;
    import org.silverpeas.components.gallery.model.OrderRow;
    import org.silverpeas.components.gallery.web.MediaSort;
    import org.silverpeas.core.admin.user.model.SilverpeasRole;
    import org.silverpeas.kernel.cache.model.SimpleCache;
    import org.silverpeas.core.contribution.content.form.DataRecord;
    import org.silverpeas.core.contribution.content.form.Field;
    import org.silverpeas.core.contribution.content.form.Form;
    import org.silverpeas.core.contribution.content.form.FormException;
    import org.silverpeas.core.contribution.content.form.PagesContext;
    import org.silverpeas.core.contribution.content.form.RecordSet;
    import org.silverpeas.core.contribution.content.form.RecordTemplate;
    import org.silverpeas.core.contribution.content.form.form.XmlSearchForm;
    import org.silverpeas.core.contribution.template.publication.PublicationTemplate;
    import org.silverpeas.core.contribution.template.publication.PublicationTemplateException;
    import org.silverpeas.core.contribution.template.publication.PublicationTemplateImpl;
    import org.silverpeas.core.importexport.report.ExportReport;
    import org.silverpeas.core.index.indexing.model.FieldDescription;
    import org.silverpeas.core.index.search.model.QueryDescription;
    import org.silverpeas.core.node.model.NodeDetail;
    import org.silverpeas.core.util.DateUtil;
    import org.silverpeas.kernel.util.StringUtil;
    import org.silverpeas.core.util.URLUtil;
    import org.silverpeas.core.util.file.FileUploadUtil;
    import org.silverpeas.kernel.logging.SilverLogger;
    import org.silverpeas.core.web.http.HttpRequest;
    import org.silverpeas.core.web.mvc.controller.ComponentContext;
    import org.silverpeas.core.web.mvc.controller.MainSessionController;
    import org.silverpeas.core.web.mvc.route.ComponentRequestRouter;
    import org.silverpeas.core.web.mvc.util.AccessForbiddenException;
    import org.silverpeas.core.webapi.pdc.PdcClassificationEntity;

    import javax.servlet.http.HttpServletRequest;
    import java.text.ParseException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Optional;
    import java.util.UUID;

    import static org.silverpeas.core.cache.service.CacheAccessorProvider.getSessionCacheAccessor;
    import static org.silverpeas.core.persistence.jdbc.sql.JdbcSqlQuery.isSqlDefined;
    import static org.silverpeas.core.util.JSONCodec.encodeObject;

    public class GalleryRequestRouter extends ComponentRequestRouter<GallerySessionController> {
      private static final long serialVersionUID = 1L;

      private static final String ORDER_VIEW_PAGIN_FUNC = "OrderViewPagin";
      private static final String ORDER_VIEW_LIST_FUNC = "OrderViewList";
      private static final String BASKET_VIEW_FUNC = "BasketView";
      private static final String VIEW_SEARCH_RESULTS_FUNC = "ViewSearchResults";
      private static final String VIEW_NOT_VISIBLE_FUNC = "ViewNotVisible";
      private static final String MEDIA_VIEW_FUNC = "MediaView";
      private static final String GO_TO_CURRENT_ALBUM_FUNC = "GoToCurrentAlbum";
      private static final String ORDER_ID = "OrderId";
      private static final String MEDIA_TYPE_ALERT_ATTR = "MediaTypeAlert";
      private static final String MEDIA_ID = "MediaId";
      private static final String IS_VIEW_LIST = "IsViewList";
      private static final String SELECTED_IDS = "SelectedIds";
      private static final String IS_VIEW_METADATA = "IsViewMetadata";
      private static final String MEDIA_RESOLUTION = "MediaResolution";
      private static final String CURRENT_ALBUM = "CurrentAlbum";
      private static final String CURRENT_PAGE_INDEX = "CurrentPageIndex";
      private static final String NB_MEDIA_PER_PAGE = "NbMediaPerPage";
      private static final String IS_BASKET = "IsBasket";
      private static final String IS_ORDER = "IsOrder";
      private static final String IS_PRIVATE_SEARCH = "IsPrivateSearch";
      private static final String IS_USE_PDC = "IsUsePdc";
      private static final String MEDIA_LIST = "MediaList";
      private static final String ALBUMS = "Albums";
      private static final String ALBUM_ID = "albumId";
      private static final String ALBUM_ID_FIRST_LETTER_UPPERCASE = "AlbumId";
      private static final String SEARCH_KEY_WORD = "SearchKeyWord";
      private static final String MEDIA_PREFIX = "media";
      private static final String UTF_8 = "UTF-8";
      private static final String DESCRIPTION = "Description";

      /**
       * This method has to be implemented in the component request rooter class. returns the session
       * control bean name to be put in the request object ex : for almanach, returns "almanach"
       */
      @Override
      public String getSessionControlBeanName() {
        return "Gallery";
      }

      @Override
      public GallerySessionController createComponentSessionController(
          MainSessionController mainSessionCtrl, ComponentContext componentContext) {
        return new GallerySessionController(mainSessionCtrl, componentContext);
      }

      @Override
      public String getDestination(String function, GallerySessionController gallerySC,
          HttpRequest request) {
        String destination = "";
        String rootDest = "/gallery/jsp/";
        request.setAttribute("gallerySC", gallerySC);

        // Set common parameters
        SilverpeasRole highestUserRole = gallerySC.getHighestSilverpeasUserRole();
        String userId = gallerySC.getUserId();

        request.setAttribute("Profile", highestUserRole.getName());
        request.setAttribute("highestUserRole", highestUserRole);
        request.setAttribute("UserId", userId);
        request.setAttribute("IsGuest", gallerySC.isGuest());
        request.setAttribute("IsAnonymous", gallerySC.isAnonymous());
        request.setAttribute("IsExportEnable", gallerySC.isExportEnable());
        request.setAttribute("Sort", gallerySC.getSort());

        try {
          if (function.startsWith("Main")) {
            // récupération des albums de 1er niveau
            gallerySC.setIndexOfCurrentPage("0");
            AlbumDetail root = gallerySC.goToAlbum("0");
            request.setAttribute("root", root);
            request.setAttribute(ALBUMS, gallerySC.addNbMedia(root.getChildrenAlbumsDetails()));
            // chercher les dernièrs médias
            Collection<Media> mediaCollection = gallerySC.getLastRegisteredMedia();
            request.setAttribute(MEDIA_LIST, mediaCollection);
            request.setAttribute(IS_USE_PDC, gallerySC.isUsePdc());
            request.setAttribute(IS_PRIVATE_SEARCH, gallerySC.isPrivateSearch());
            request.setAttribute(IS_BASKET, gallerySC.isBasket());
            request.setAttribute(IS_ORDER, gallerySC.isOrder());
            destination = rootDest + "welcome.jsp";
          } else if ("ManageComponentSubscriptions".equals(function)) {
            destination = gallerySC.manageComponentSubscriptions();
          } else if ("ManageAlbumSubscriptions".equals(function)) {
            destination = gallerySC.manageAlbumSubscriptions();
          } else if ("ViewAlbum".equals(function)) {
            if (StringUtil.isDefined(request.getParameter("deselectAll"))) {
              deselectAll(gallerySC);
            }
            // récupération de l'Id de l'album en cours
            String albumId = request.getParameter("Id");
            gallerySC.goToAlbum(albumId);
            gallerySC.setIndexOfCurrentPage("0");
            // Slideshow requirements
            request.setAttribute(ALBUM_ID, albumId);
            request.setAttribute("wait", gallerySC.getSlideshowWait());
            // retour à l'album courant
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if ("Pagination".equals(function)) {
            processSelection(request, gallerySC);

            // traitement de la pagination : passage des paramètres
            String index = request.getParameter("Index");
            if (index != null && !index.isEmpty()) {
              gallerySC.setIndexOfCurrentPage(index);
            }
            String nbItemsPerPage = request.getParameter("NbItemsPerPage");
            if (StringUtil.isInteger(nbItemsPerPage)) {
              gallerySC.setNbMediasPerPage(Integer.parseInt(nbItemsPerPage));
            }
            destination = returnToAlbum(request, gallerySC);

          } else if (GO_TO_CURRENT_ALBUM_FUNC.equals(function)) {
            // mise à blanc de l'index de pagination si on arrive de la recherche
            if (gallerySC.isSearchResult() || gallerySC.isViewNotVisible()) {
              gallerySC.setIndexOfCurrentPage("0");
            }
            // mise à blanc de la liste des médias (pour les mots clé et pour les médias non visibles)
            gallerySC.setRestrictedListMedia(new ArrayList<>());
            gallerySC.setSearchResult(false);
            gallerySC.setViewNotVisible(false);

            // récupération de l'album en cours
            String currentAlbumId = gallerySC.getCurrentAlbumId();
            if ("0".equals(currentAlbumId)) {
              // on est à la racine, on retourne à l'accueil
              destination = getDestination("Main", gallerySC, request);
            } else {
              // on est dans un album, on y retourne
              AlbumDetail currentAlbum = gallerySC.goToAlbum();
              request.setAttribute(NB_MEDIA_PER_PAGE, gallerySC.getNbMediaPerPage());
              request.setAttribute(CURRENT_PAGE_INDEX, gallerySC.getIndexOfCurrentPage());
              request.setAttribute(CURRENT_ALBUM, currentAlbum);
              request.setAttribute(ALBUM_ID, currentAlbum.getId());
              request.setAttribute(ALBUMS,
                  gallerySC.addNbMedia(currentAlbum.getChildrenAlbumsDetails()));
              request.setAttribute("Path", gallerySC.getPath(currentAlbum.getNodePK()));
              request.setAttribute(MEDIA_RESOLUTION, gallerySC.getDisplayedMediaResolution());
              request.setAttribute("DragAndDropEnable", gallerySC.isDragAndDropEnabled());
              request.setAttribute(IS_VIEW_METADATA, gallerySC.isViewMetadata());
              request.setAttribute(IS_VIEW_LIST, gallerySC.isViewList());
              request.setAttribute(SELECTED_IDS, gallerySC.getListSelected());
              request.setAttribute(IS_USE_PDC, gallerySC.isUsePdc());
              request.setAttribute(IS_BASKET, gallerySC.isBasket());
              request.setAttribute(IS_ORDER, gallerySC.isOrder());
              request.setAttribute(IS_PRIVATE_SEARCH, gallerySC.isPrivateSearch());

              destination = rootDest + "viewAlbum.jsp";
            }
          } else if ("NewAlbum".equals(function)) {
            // passage de l'album courant : null car en création
            request.setAttribute(CURRENT_ALBUM, null);
            request.setAttribute("Path", gallerySC.getPath());
            // appel jsp
            destination = rootDest + "albumManager.jsp";
          } else if ("CreateAlbum".equals(function)) {
            // check user rights
            if (!gallerySC.isAlbumAdmin(highestUserRole, null, userId)) {
              throw new AccessForbiddenException("Gallery creation forbidden");
            }

            // récupération des paramètres de l'album
            String name = request.getParameter("Name");
            String description = request.getParameter(DESCRIPTION);
            // création de l'album
            NodeDetail node =
                new NodeDetail("unknown", name, description, 0, "unknown");
            AlbumDetail album = new AlbumDetail(node);
            gallerySC.createAlbum(album);
            // retour à l'album courant
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if ("EditAlbum".equals(function)) {
            // récupération des paramètres
            String albumId = request.getParameter("Id");

            // check user rights
            if (!gallerySC.isAlbumAdmin(highestUserRole, albumId, userId)) {
              throw new AccessForbiddenException("Gallery edition forbidden");
            }

            // récupération de l'album courant
            AlbumDetail currentAlbum = gallerySC.getAlbum(albumId);
            // passage des paramètres
            request.setAttribute(CURRENT_ALBUM, currentAlbum);
            request.setAttribute("Path", gallerySC.getPath());
            destination = rootDest + "albumManager.jsp";
          } else if ("UpdateAlbum".equals(function)) {
            String albumId = request.getParameter("Id");

            // check user rights
            if (!gallerySC.isAlbumAdmin(highestUserRole, albumId, userId)) {
              throw new AccessForbiddenException("Gallery update forbidden");
            }

            // Retrieve album name and description
            String name = request.getParameter("Name");
            String description = request.getParameter(DESCRIPTION);

            // Retrieve current album
            AlbumDetail album = gallerySC.getAlbum(albumId);
            // set new value
            album.setName(name);
            album.setDescription(description);

            gallerySC.updateAlbum(album);
            // retour à l'album courant
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if ("DeleteAlbum".equals(function)) {
            // Retrieve album identifier to delete
            String albumId = request.getParameter("Id");

            // check user rights
            if (!gallerySC.isAlbumAdmin(highestUserRole, albumId, userId)) {
              throw new AccessForbiddenException("Gallery deletion forbidden");
            }

            gallerySC.deleteAlbum(albumId);
            // retour à l'album courant
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if ("AddMedia".equals(function)) {
            // check user rights
            if (!gallerySC.isMediaAdmin(highestUserRole, null, userId)) {
              throw new AccessForbiddenException("Media adding forbidden");
            }
            MediaType mediaType = MediaType.from(request.getParameter("type"));

            // passage des paramètres
            request.setAttribute("Media", mediaType.newInstance());
            request.setAttribute("Repertoire", "");
            request.setAttribute("Path", gallerySC.getPath());
            request.setAttribute("GetLanguage", gallerySC.getLanguage());
            request.setAttribute("UserName", gallerySC.getUserDetail(userId).getDisplayedName());
            request.setAttribute("NbComments", 0);
            request.setAttribute(IS_USE_PDC, gallerySC.isUsePdc());
            request.setAttribute("XMLFormName", gallerySC.getXMLFormName());
            request.setAttribute("ShowCommentsTab", gallerySC.areCommentsEnabled());
            request.setAttribute(IS_BASKET, gallerySC.isBasket());
            request.setAttribute(IS_ORDER, gallerySC.isOrder());
            request.setAttribute(IS_VIEW_METADATA, gallerySC.isViewMetadata());

            // prepare xml form data
            PublicationTemplate template = gallerySC.getTemplate();
            if (template != null) {
              RecordSet recordSet = template.getRecordSet();
              request.setAttribute("Form", template.getUpdateForm());
              request.setAttribute("Data", recordSet.getEmptyRecord());
            }

            destination = rootDest + MEDIA_PREFIX + mediaType + "Edit.jsp";
          } else if ("CreateMedia".equals(function)) {

            if (!StringUtil.isDefined(request.getCharacterEncoding())) {
              request.setCharacterEncoding(UTF_8);
            }

            // check user rights
            if (!gallerySC.isMediaAdmin(highestUserRole, null, userId)) {
              throw new AccessForbiddenException("Media creation forbidden");
            }

            final String mediaId = createMediaData(request, gallerySC);

            // Reload the album
            gallerySC.loadCurrentAlbum();

            // preview of the new media
            request.setAttribute(MEDIA_ID, mediaId);
            destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
          } else if ("UpdateMedia".equals(function) || "UpdateInformation".equals(function)) {
            boolean isUpdateMediaFromAlbumCase =
                StringUtil.getBooleanValue(request.getParameter("isUpdateMediaFromAlbumCase"));
            if (!StringUtil.isDefined(request.getCharacterEncoding())) {
              request.setCharacterEncoding(UTF_8);
            }
            List<FileItem> parameters = request.getFileItems();
            String mediaId = FileUploadUtil
                .getParameter(parameters, MEDIA_ID, null, request.getCharacterEncoding());
            updateMediaData(mediaId, request, gallerySC);
            if (isUpdateMediaFromAlbumCase) {
              // Reload and clean the current album
              gallerySC.loadCurrentAlbum();
              deselectAll(gallerySC);
              // Back to the current album
              destination = returnToAlbum(request, gallerySC);
            } else {
              // Back to the view of the updated media
              request.setAttribute(MEDIA_ID, mediaId);
              destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
            }
          } else if ("DeleteMedia".equals(function)) {
            // Retrieve media identifier to delete
            String mediaId = request.getParameter(MEDIA_ID);

            // check user rights
            if (!gallerySC.isMediaAdmin(highestUserRole, mediaId, userId)) {
              throw new AccessForbiddenException("Media deletion forbidden");
            }
            gallerySC.deleteMedia(mediaId);

            // retour à l'album courant
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if (MEDIA_VIEW_FUNC.equals(function)) {
            // mise à blanc de la liste restreintes des médias (pour les médias non visibles)
            gallerySC.setRestrictedListMedia(new ArrayList<>());
            // remise à blanc des médias selectionnés
            deselectAll(gallerySC);
            // récupération des paramètres
            String mediaId = request.getParameter(MEDIA_ID);
            if (mediaId == null || mediaId.isEmpty() || "null".equals(mediaId)) {
              mediaId = (String) request.getAttribute(MEDIA_ID);
            }
            request.setAttribute(IS_PRIVATE_SEARCH, gallerySC.isPrivateSearch());
            destination = processMedia(gallerySC, request, rootDest, highestUserRole, mediaId);
          } else if ("PreviousMedia".equals(function)) {
            Media media = gallerySC.getPrevious();
            request.setAttribute(MEDIA_ID, media.getId());
            destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
          } else if ("NextMedia".equals(function)) {
            Media media = gallerySC.getNext();
            request.setAttribute(MEDIA_ID, media.getId());
            destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
          } else if (function.startsWith("searchResult")) {
            // traitement des recherches
            String id = request.getParameter("Id");
            String type = request.getParameter("Type");
            destination = processMediaType(gallerySC, request, id, type);
          } else if ("AccessPath".equals(function)) {

            // visualisation des emplacements
            request.setAttribute("Path", gallerySC.getPath());
            // récupération du média
            String mediaId = request.getParameter(MEDIA_ID);
            if (mediaId == null || mediaId.isEmpty()) {
              mediaId = request.getParameter("PubId");
            }
            if (mediaId == null || mediaId.isEmpty()) {
              mediaId = (String) request.getAttribute(MEDIA_ID);
            }

            // check user rights
            if (!gallerySC.isMediaAdmin(highestUserRole, mediaId, userId)) {
              throw new AccessForbiddenException("Gallery access forbidden");
            }

            Media media = gallerySC.getMedia(mediaId);

            // passage des paramètres
            putMediaCommonParameters(request, gallerySC, media, highestUserRole);

            request.setAttribute("PathList", gallerySC.getAlbumIdsOf(mediaId));
            request.setAttribute(ALBUMS, gallerySC.getAllAlbums());

            destination = rootDest + "albumsOfMedia.jsp";
          } else if ("SelectPath".equals(function)) {
            // modification de la liste des emplacements du média
            String[] albums = request.getParameterValues("albumChoice");
            String mediaId = request.getParameter(MEDIA_ID);

            // check user rights
            if (!gallerySC.isMediaAdmin(highestUserRole, mediaId, userId)) {
              throw new AccessForbiddenException("Media access forbidden");
            }

            gallerySC.setMediaToAlbums(mediaId, albums);
            destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
          } else if ("AskMedia".equals(function)) {
            // demande de médias auprès du gestionnaire de la médiathèque
            destination = rootDest + "askMedia.jsp";
          } else if ("SendAsk".equals(function)) {
            // envoie d'une notification au gestionnaire
            String description = request.getParameter(DESCRIPTION);
            gallerySC.sendAskMedia(description);
            destination = rootDest + "closeWindow.jsp";
          } else if ("ChoiceSize".equals(function)) {
            // traitement du choix des tailles
            String choix = request.getParameter("Choice");
            // mettre à jour la taille avec le choix
            gallerySC.setDisplayedMediaResolution(MediaResolution.fromNameOrLabel(choix));
            // retourner au début de la liste des médias
            gallerySC.initIndex();
            // retour ... en fonction d'ou on viens
            destination = returnToAlbum(request, gallerySC);

          } else if ("SortBy".equals(function)) {
            // traitement du tri selon l'écran en cours
            MediaSort sort = MediaSort.from(request.getParameter("Sort"));
            if ((!gallerySC.isSearchResult() && !gallerySC.isViewNotVisible())) {
              gallerySC.setSort(sort);
            } else {
              gallerySC.setSortSearch(sort);
            }
            destination = returnToAlbum(request, gallerySC);
          } else if ("EditSelectedMedia".equals(function)) {
            // traitement par lot
            String albumId = request.getParameter(ALBUM_ID_FIRST_LETTER_UPPERCASE);

            // check user rights
            if (!highestUserRole.isGreaterThanOrEquals(SilverpeasRole.PUBLISHER)) {
              throw new AccessForbiddenException("Media edition fobidden");
            }

            String searchKeyWord = request.getParameter(SEARCH_KEY_WORD);

            processSelection(request, gallerySC);

            // liste des médias sélectionnés
            if (!gallerySC.getListSelected().isEmpty()) {
              if (gallerySC.getListSelected().size() == 1) {
                // One media is being to be edited, the user is redirected to the edit page of the media
                request.setAttribute("MediaIdFromAlbum", gallerySC.getListSelected().iterator().next());
                destination = getDestination("EditInformation", gallerySC, request);
              } else {
                // passage des paramètres globaux
                request.setAttribute("SelectedMediaIds", gallerySC.getListSelected());
                request.setAttribute(ALBUM_ID_FIRST_LETTER_UPPERCASE, albumId);
                request.setAttribute(SEARCH_KEY_WORD, searchKeyWord);
                request.setAttribute("Path", gallerySC.getPath());
                request.setAttribute("GetLanguage", gallerySC.getLanguage());

                // passage des paramètres pour le formulaire
                PublicationTemplate template = gallerySC.getTemplate();
                if (template != null) {
                  RecordSet recordSet = template.getRecordSet();
                  request.setAttribute("Form", template.getUpdateForm());
                  request.setAttribute("Data", recordSet.getEmptyRecord());
                }

                destination = rootDest + "selectedMediaManager.jsp";
              }
            } else {
              destination = returnToAlbum(request, gallerySC);
            }
          } else if ("UpdateSelectedMedia".equals(function)) {
            // récupération des médias modifiés
            Collection<String> mediaIds = gallerySC.getListSelected();

            // mise à jour des médias
            if (!StringUtil.isDefined(request.getCharacterEncoding())) {
              request.setCharacterEncoding(UTF_8);
            }
            updateSelectedMedia(request, gallerySC, mediaIds, request.getCharacterEncoding());

            // tout déselectionner
            deselectAll(gallerySC);
            destination = returnToAlbum(request, gallerySC);

          } else if ("UpdateSelectedPaths".equals(function)) {
            // récupération des médias modifiés
            Collection<String> mediaIds = gallerySC.getListSelected();

            // mise à jour des emplacements des médias
            String[] albums = request.getParameterValues("albumChoice");

            for (String mediaId : mediaIds) {
              if (gallerySC.isMediaAdmin(highestUserRole, mediaId, userId)) {
                // ajouter les nouveau emplacements sur les anciens
                gallerySC.addMediaToAlbums(mediaId, albums);
              }
            }
            deselectAll(gallerySC);

            destination = returnToAlbum(request, gallerySC);
          } else if ("DeleteSelectedMedia".equals(function)) {
            processSelection(request, gallerySC);

            // liste des médias sélectionnés
            if (!gallerySC.getListSelected().isEmpty()) {
              // récupération des médias à supprimer
              Collection<String> mediaIds = gallerySC.getListSelected();

              // suppression des médias
              deleteSelectedMedia(gallerySC, mediaIds);

              deselectAll(gallerySC);

              // retour à l'album en cours
              destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
            }
          } else if ("CategorizeSelectedMedia".equals(function)) {
            processSelection(request, gallerySC);

            // liste des médias sélectionnés
            if (!gallerySC.getListSelected().isEmpty()) {
              final List<String> selectedIds = (List<String>) gallerySC.getListSelected();

              // get silverObjectIds according to selected mediaIds
              final List<String> silverObjectIds = new ArrayList<>();
              for (final String selectedId : selectedIds) {
                silverObjectIds.add(Integer.toString(gallerySC.getSilverObjectId(selectedId)));
              }

              request.setAttribute("ObjectIds", silverObjectIds);
              request.setAttribute("ComponentId", gallerySC.getComponentId());
              destination = "/RpdcClassify/jsp/ToAddPositions";
            } else {
              destination = rootDest + "closeWindow.jsp";
            }
          } else if ("AddAlbumForSelectedMedia".equals(function)) {
            // placement par lot
            String albumId = request.getParameter(ALBUM_ID_FIRST_LETTER_UPPERCASE);
            // check user rights
            if (!highestUserRole.isGreaterThanOrEquals(SilverpeasRole.PUBLISHER)) {
              throw new AccessForbiddenException("Media adding into gallery forbidden");
            }
            processSelection(request, gallerySC);
            // liste des médias sélectionnés
            if (!gallerySC.getListSelected().isEmpty()) {
              // passage des paramètres globaux
              request.setAttribute(ALBUM_ID_FIRST_LETTER_UPPERCASE, albumId);
              request.setAttribute("Path", gallerySC.getPath());
              request.setAttribute(ALBUMS, gallerySC.getAllAlbums());

              destination = rootDest + "pathsManager.jsp";
            } else {
              destination = returnToAlbum(request, gallerySC);
            }
          } else if ("EditInformation".equals(function)) {
            // récupération des paramètres
            String mediaId = request.getParameter(MEDIA_ID);
            if (StringUtil.isNotDefined(mediaId)) {
              // Firstly, verifying that the user tries to modify a media from album
              mediaId = (String) request.getAttribute("MediaIdFromAlbum");
              if (StringUtil.isDefined(mediaId)) {
                request.setAttribute("isUpdateMediaFromAlbumCase", true);
              }
            }
            // récupération du média
            Media media = gallerySC.getMedia(mediaId);

            // passage des paramètres
            putMediaCommonParameters(request, gallerySC, media, highestUserRole);

            request.setAttribute(IS_VIEW_METADATA, gallerySC.isViewMetadata());

            request.setAttribute("Repertoire", media.getWorkspaceSubFolderName());

            // récupération du formulaire et affichage
            PublicationTemplate template = gallerySC.getTemplate();
            if (template != null) {
              RecordSet recordSet = template.getRecordSet();
              DataRecord data = recordSet.getRecord(mediaId);
              if (data == null) {
                data = recordSet.getEmptyRecord();
                data.setId(mediaId);
              }
              request.setAttribute("Form", template.getUpdateForm());
              request.setAttribute("Data", data);
            }

            // appel jsp
            destination = rootDest + MEDIA_PREFIX + media.getType().name() + "Edit.jsp";
          } else if ("AllSelected".equals(function)) {
            // sélectionne (ou déselectionne) tous les médias de l'album (ou de la liste restreinte
            // dans le cas de la recherche)
            boolean select = !gallerySC.getSelect();
            gallerySC.setSelect(select);

            Collection<Media> media;

            // Returning to the from
            if (!gallerySC.isSearchResult() && !gallerySC.isViewNotVisible()) {
              // Returning to the album
              media = gallerySC.goToAlbum().getMedia();

              if (select) {
                gallerySC.getListSelected().addAll(extractIds(media));
              } else {
                gallerySC.getListSelected().removeAll(extractIds(media));
              }

              destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);

            } else {
              // Returning to search result or to not visible list
              if (gallerySC.isViewNotVisible()) {
                media = gallerySC.getNotVisible();

                if (select) {
                  gallerySC.getListSelected().addAll(extractIds(media));
                } else {
                  gallerySC.getListSelected().removeAll(extractIds(media));
                }

                gallerySC.setRestrictedListMedia(media);
                destination = getDestination(VIEW_NOT_VISIBLE_FUNC, gallerySC, request);
              } else {
                media = gallerySC.getSearchResultListMedia();

                if (select) {
                  gallerySC.getListSelected().addAll(extractIds(media));
                } else {
                  gallerySC.getListSelected().removeAll(extractIds(media));
                }

                destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);

              }
            }
          } else if ("SearchAdvanced".equals(function)) {
            // recherche avancée
            request.setAttribute("MetaDataKeys", gallerySC.getMetaDataKeys());

            // récupérer le contexte
            QueryDescription query = gallerySC.getQuery();

            // passage des paramètre pour garder le contexte
            String keyWord = query.getQuery();
            request.setAttribute("KeyWord", keyWord);

            // contexte de recherche du PDC
            request.setAttribute("PDCSearchContext", gallerySC.getPDCSearchContext());

            // pour les formulaires
            PublicationTemplate template = gallerySC.getTemplate();
            if (template != null) {
              // get previous search
              DataRecord data = gallerySC.getXMLSearchContext();
              if (data == null) {
                RecordSet recordSet = template.getRecordSet();
                data = recordSet.getEmptyRecord();
              }
              request.setAttribute("Form", template.getSearchForm());
              request.setAttribute("Data", data);
            }

            destination = rootDest + "searchAdvanced.jsp";
          } else if ("ClearSearch".equals(function)) {
            gallerySC.clearSearchContext();

            destination = getDestination("SearchAdvanced", gallerySC, request);
          } else if ("LastResult".equals(function)) {
            // Reset pagination index
            gallerySC.setIndexOfCurrentPage("0");

            destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);
          } else if (SEARCH_KEY_WORD.equals(function)) {
            // traitement de la recherche par mot clé
            // et de la recherche dédiée
            // récupération du mot clé et de la liste des médias concernés si il existe
            String searchKeyWord = request.getParameter(SEARCH_KEY_WORD);
            if (searchKeyWord == null) {
              searchKeyWord = (String) request.getAttribute(SEARCH_KEY_WORD);
            }
            if (!isDefined(searchKeyWord)) {
              searchKeyWord = gallerySC.getSearchKeyWord();
            }

            // Reset search if keyword has changed
            if (!gallerySC.getSearchKeyWord().equals(searchKeyWord)) {
              gallerySC.setSearchResultListMedia(new ArrayList<>());
              gallerySC.setSearchKeyWord(searchKeyWord);
              // reset pagination index
              gallerySC.setIndexOfCurrentPage("0");
            }

            // mise à jour du tag pour les retours
            gallerySC.setViewNotVisible(false);
            gallerySC.setSearchResult(true);

            QueryDescription query = new QueryDescription(searchKeyWord);

            if (StringUtil.isDefined(query.getQuery())) {
              gallerySC.setSearchResultListMedia(gallerySC.search(query));
            }

            destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);
          } else if ("PaginationSearch".equals(function)) {
            processSelection(request, gallerySC);

            // traitement de la pagination : passage des paramètres
            String index = request.getParameter("Index");
            if (index != null && !index.isEmpty()) {
              gallerySC.setIndexOfCurrentPage(index);
            }

            destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);
          } else if (VIEW_SEARCH_RESULTS_FUNC.equals(function)) {
            Collection<Media> media = gallerySC.getSearchResultListMedia();
            // passage des paramètres
            setDefaultRequestAttributes(gallerySC, media, gallerySC.getSearchKeyWord(), request);

            // mise à jour du tag pour les retours
            gallerySC.setSearchResult(true);
            gallerySC.setViewNotVisible(false);
            request.setAttribute(VIEW_NOT_VISIBLE_FUNC, gallerySC.isViewNotVisible());

            // appel jsp
            destination = rootDest + "viewRestrictedMediaList.jsp";
          } else if ("Search".equals(function)) {
            if (!StringUtil.isDefined(request.getCharacterEncoding())) {
              request.setCharacterEncoding(UTF_8);
            }
            List<FileItem> items = request.getFileItems();
            QueryDescription query = new QueryDescription();
            // Ajout de la requete classique
            String word = FileUploadUtil
                .getParameter(items, SEARCH_KEY_WORD, null, request.getCharacterEncoding());
            query.setQuery(word);
            gallerySC.setSearchKeyWord(word);

            // Ajout des éléments de recherche sur form XML
            PublicationTemplateImpl template = (PublicationTemplateImpl) gallerySC.getTemplate();
            if (template != null) {
              String templateFileName = template.getFileName();
              String templateName = templateFileName.substring(0, templateFileName.lastIndexOf('.'));

              RecordTemplate searchTemplate = template.getSearchTemplate();
              if (searchTemplate != null) {
                DataRecord data = searchTemplate.getEmptyRecord();

                PagesContext context = new PagesContext("XMLSearchForm", "2", gallerySC.getLanguage(),
                    gallerySC.getUserId());
                context.setEncoding(UTF_8);
                XmlSearchForm searchForm = (XmlSearchForm) template.getSearchForm();
                searchForm.update(items, data, context);

                // store xml search data in session
                gallerySC.setXMLSearchContext(data);

                for (final String fieldName : searchTemplate.getFieldNames()) {
                  Field field = data.getField(fieldName);
                  String fieldValue = field.getStringValue();
                  if (fieldValue != null && !fieldValue.trim().isEmpty()) {
                    String fieldQuery = fieldValue.trim().replaceAll("##", " AND "); // case à cocher
                    // multiple
                    query.addFieldQuery(
                        new FieldDescription(templateName + "$$" + fieldName, fieldQuery, null));
                  }
                }
              }
            }

            // Add IPTC search elements
            List<MetaData> iptcFields = gallerySC.getMetaDataKeys();
            // Loop for each xml fields
            for (final MetaData iptcField : iptcFields) {
              // recuperation valeur dans request
              String property = iptcField.getProperty();

              // ajouter à l'objet query
              if (!iptcField.isDate()) {
                String value =
                    FileUploadUtil.getParameter(items, property, null, request.getCharacterEncoding());
                if (StringUtil.isDefined(value)) {
                  query.addFieldQuery(new FieldDescription("IPTC_" + property, value, null));
                }
              } else {
                // cas particulier des champs de type date
                // recupere les deux champs
                String dateBeginStr = FileUploadUtil
                    .getParameter(items, property + "_Begin", null, request.getCharacterEncoding());
                String dateEndStr = FileUploadUtil
                    .getParameter(items, property + "_End", null, request.getCharacterEncoding());

                Date dateBegin = null;
                Date dateEnd = null;

                if (StringUtil.isDefined(dateBeginStr)) {
                  dateBegin = DateUtil.stringToDate(dateBeginStr, gallerySC.getLanguage());
                }

                if (StringUtil.isDefined(dateEndStr)) {
                  dateEnd = DateUtil.stringToDate(dateEndStr, gallerySC.getLanguage());
                }

                if (dateBegin != null || dateEnd != null) {
                  query.addFieldQuery(new FieldDescription("IPTC_" + property,
                      dateBegin, dateEnd, null));
                }

              }
            }

            // Ajout élément PDC
            String axisValues = request.getParameter("AxisValueCouples");
            query.setTaxonomyPosition(axisValues);

            // Lancement de la recherche
            gallerySC.search(query);

            destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);
          } else if (VIEW_NOT_VISIBLE_FUNC.equals(function)) {
            // traitement de la liste des médias plus visibles
            // récupération de la liste des médias plus visibles, ou création de cette liste si elle est
            // vide
            Collection<Media> media = gallerySC.getRestrictedListMedia();
            if (media.isEmpty()) {
              media = gallerySC.getNotVisible();
            }

            // mise à jour du tag pour les médias non visibles
            gallerySC.setSearchResult(false);
            gallerySC.setViewNotVisible(true);
            request.setAttribute(VIEW_NOT_VISIBLE_FUNC, gallerySC.isViewNotVisible());

            // passage des paramètres
            setDefaultRequestAttributes(gallerySC, media, "", request);

            destination = rootDest + "viewRestrictedMediaList.jsp";
          } else if (function.startsWith("portlet")) {
            // récupération des albums de 1er niveau
            gallerySC.setIndexOfCurrentPage("0");
            request.setAttribute("root", gallerySC.goToAlbum("0"));
            // chercher les derniers médias
            Collection<Media> mediaList = gallerySC.getLastRegisteredMedia();
            request.setAttribute(MEDIA_LIST, mediaList);
            destination = rootDest + "portlet.jsp";
          } else if ("copy".equals(function)) {
            String objectType = request.getParameter("Object");
            String objectId = request.getParameter("Id");
            if (StringUtil.isDefined(objectType) && "Node".equalsIgnoreCase(objectType)) {
              gallerySC.copyAlbum(objectId);
            } else {
              gallerySC.copyMedia(objectId);
            }
            destination =
                URLUtil.getURL(URLUtil.CMP_CLIPBOARD, null, null) +
                    "Idle.jsp?message=REFRESHCLIPBOARD";
          } else if ("CopySelectedMedia".equals(function)) {
            processSelection(request, gallerySC);
            // check list of selected media
            if (!gallerySC.getListSelected().isEmpty()) {
              // retrieve media to copy
              Collection<String> mediaIds = gallerySC.getListSelected();
              // copy media
              gallerySC.copySelectedMedia(mediaIds);
              deselectAll(gallerySC);
            }
            // Get back to current album view
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if ("cut".startsWith(function)) {
            String objectType = request.getParameter("Object");
            String objectId = request.getParameter("Id");
            if (StringUtil.isDefined(objectType) && "Node".equalsIgnoreCase(objectType)) {
              gallerySC.cutAlbum(objectId);
            } else {
              gallerySC.cutMedia(objectId);
            }
            destination =
                URLUtil.getURL(URLUtil.CMP_CLIPBOARD, null, null) +
                    "Idle.jsp?message=REFRESHCLIPBOARD";
          } else if ("CutSelectedMedia".equals(function)) {
            processSelection(request, gallerySC);

            if (!gallerySC.getListSelected().isEmpty()) {
              Collection<String> mediaIds = gallerySC.getListSelected();
              gallerySC.cutSelectedMedia(mediaIds);
              deselectAll(gallerySC);
            }
            // Get back to current album view
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if (function.startsWith("paste")) {
            gallerySC.paste();
            gallerySC.loadCurrentAlbum();
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          } else if (function.startsWith("Basket")) {
            // Manage basket functions
            switch (function) {
              case BASKET_VIEW_FUNC:
                // Basket view
                request.setAttribute(MEDIA_LIST, gallerySC.getBasketMedias());
                request.setAttribute(NB_MEDIA_PER_PAGE, gallerySC.getNbMediaPerPage());
                request.setAttribute(SELECTED_IDS, gallerySC.getListSelected());
                request.setAttribute(IS_ORDER, gallerySC.isOrder());
                request.setAttribute(MEDIA_TYPE_ALERT_ATTR,
                    request.getAttribute(MEDIA_TYPE_ALERT_ATTR));

                destination = rootDest + "basket.jsp";
                break;
              case "BasketDelete":
                gallerySC.clearBasket();
                destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                break;
              case "BasketDeleteMedia": {
                // Delete media from basket
                String mediaId = request.getParameter(MEDIA_ID);
                gallerySC.deletePhotoFromBasket(mediaId);

                destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                break;
              }
              case "BasketDeleteSelectedMedia":
                // delete selected medias from basket
                processSelection(request, gallerySC);
                if (!gallerySC.getListSelected().isEmpty()) {
                  gallerySC.deleteSelectedPhotosFromBasket();
                }
                destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                break;
              case "BasketAddMediaList":
                // Add selected photo media inside basket
                processSelection(request, gallerySC);
                if (!gallerySC.getListSelected().isEmpty()) {
                  if (!gallerySC.addToBasket()) {
                    request.setAttribute(MEDIA_TYPE_ALERT_ATTR, true);
                  }
                  destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                } else {
                  destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
                }
                break;
              case "BasketAddMedia": {
                // Add this media inside basket
                String mediaId = request.getParameter(MEDIA_ID);
                gallerySC.addMediaToBasket(mediaId);
                destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                break;
              }
              case "BasketPagination":
                processSelection(request, gallerySC);

                // retour au panier
                destination = getDestination(BASKET_VIEW_FUNC, gallerySC, request);
                break;
            }
          } else if (function.startsWith("Order")) {
            switch (function) {
              case "OrderAdd": {
                // Retrieve order form
                PublicationTemplate template = gallerySC.getOrderTemplate();
                if (template != null) {
                  RecordSet recordSet = template.getRecordSet();
                  request.setAttribute("Form", template.getUpdateForm());
                  request.setAttribute("Data", recordSet.getEmptyRecord());
                }

                // retrieve convention
                String charteUrl = gallerySC.getCharteUrl();
                request.setAttribute("CharteUrl", charteUrl);

                destination = rootDest + "basketForm.jsp";
                break;
              }
              case "OrderCreate": {
                // create order from basket
                String orderId = gallerySC.addOrder();

                // mise à jour des données du formulaire
                if (!StringUtil.isDefined(request.getCharacterEncoding())) {
                  request.setCharacterEncoding(UTF_8);
                }
                List<FileItem> items = request.getFileItems();

                PublicationTemplate template = gallerySC.getOrderTemplate();
                if (template != null) {
                  RecordSet set = template.getRecordSet();
                  Form form = template.getUpdateForm();
                  DataRecord data = set.getRecord(orderId);
                  if (data == null) {
                    data = set.getEmptyRecord();
                    data.setId(orderId);
                  }

                  PagesContext context = new PagesContext("myForm", "0", gallerySC.getLanguage(), false,
                      gallerySC.getComponentId(), gallerySC.getUserId());
                  context.setEncoding(UTF_8);
                  context.setObjectId(orderId);

                  // mise à jour des données saisies
                  form.update(items, data, context);
                  set.save(data);
                }

                // notify gallery manager
                gallerySC.sendAskOrder(orderId);

                // view order list destination
                destination = getDestination(ORDER_VIEW_LIST_FUNC, gallerySC, request);
                break;
              }
              case "OrderUpdate": {
                String orderId = request.getParameter(ORDER_ID);
                // update order
                updateOrder(request, gallerySC, orderId, userId);
                // notify reader user
                gallerySC.sendAskOrderUser(orderId);
                destination = getDestination(ORDER_VIEW_LIST_FUNC, gallerySC, request);
                break;
              }
              case ORDER_VIEW_LIST_FUNC:
                Collection<Order> orders;
                if (highestUserRole == SilverpeasRole.ADMIN) {
                  // if manager retrieve all orders
                  orders = gallerySC.getAllOrders();
                } else {
                  // else if retrieve only user orders
                  orders = gallerySC.getOrdersByUser();
                }
                request.setAttribute("NbOrdersProcess", getNbOrdersProcess(orders));
                request.setAttribute("Orders", orders);
                destination = rootDest + "orders.jsp";
                break;
              case "OrderView": {
                String orderId = request.getParameter(ORDER_ID);
                if (orderId == null || orderId.isEmpty() || "null".equals(orderId)) {
                  orderId = (String) request.getAttribute(ORDER_ID);
                }

                if (highestUserRole == SilverpeasRole.ADMIN || gallerySC.isAccessAuthorized(orderId)) {
                  gallerySC.setCurrentOrderId(orderId);

                  destination = getDestination(ORDER_VIEW_PAGIN_FUNC, gallerySC, request);
                } else {
                  destination = "/admin/jsp/accessForbidden.jsp";
                }
                break;
              }
              case ORDER_VIEW_PAGIN_FUNC: {
                String orderId = gallerySC.getCurrentOrderId();
                request.setAttribute("Order", gallerySC.getOrder(orderId));
                request.setAttribute(NB_MEDIA_PER_PAGE, gallerySC.getNbMediaPerPage());

                PublicationTemplate template = gallerySC.getOrderTemplate();
                if (template != null) {
                  RecordSet recordSet = template.getRecordSet();
                  DataRecord data = recordSet.getRecord(orderId);
                  if (data != null) {
                    request.setAttribute("XMLForm", template.getViewForm());
                    request.setAttribute("XMLData", data);
                  }
                }
                destination = rootDest + "order.jsp";
                break;
              }
              case "OrderPagination":
                // retour à la demande
                destination = getDestination(ORDER_VIEW_PAGIN_FUNC, gallerySC, request);
                break;
              case "OrderDownloadMedia":
                final SimpleCache cache = getSessionCacheAccessor().getCache();
                destination = Optional.ofNullable(request.getParameter("downloadId"))
                    .filter(StringUtil::isDefined)
                    .map(d -> Optional.ofNullable(cache.remove(d, String.class))
                        .filter(StringUtil::isDefined)
                        .map(u -> u.replace(URLUtil.getApplicationURL(), StringUtil.EMPTY))
                        .orElseGet(() -> getDestination(ORDER_VIEW_PAGIN_FUNC, gallerySC, request)))
                    .orElseGet(() -> {
                      final String mediaId = request.getParameter(MEDIA_ID);
                      final String orderId = request.getParameter(ORDER_ID);
                      return Optional.of(gallerySC.getUrl(orderId, mediaId))
                          .filter(StringUtil::isDefined)
                          .map(u -> {
                            gallerySC.updateOrderRow(orderId, mediaId);
                            final String downloadUrlKey = UUID.randomUUID().toString();
                            cache.put(downloadUrlKey, u);
                            return sendJson(encodeObject(o -> o.put("downloadId", downloadUrlKey)));
                          }).orElseGet(() -> {
                            final String errorMessage = gallerySC.getString("gallery" +
                                ".alreadyDownloaded");
                            return sendJson(encodeObject(o -> o.put("errorMessage", errorMessage)));
                          });
                    });
                break;
            }
          } else if (function.startsWith("Export")) {
            if ("ExportAlbum".equals(function)) {
              String albumId = request.getParameter(ALBUM_ID);
              String format = request.getParameter("format");
              ExportReport exportRpt =
                  gallerySC.exportAlbum(albumId, MediaResolution.fromNameOrLabel(format));
              request.setAttribute("ExportReport", exportRpt);
              destination = rootDest + "downloadZip.jsp";
            } else if ("ExportSelection".equals(function)) {
              String format = request.getParameter("format");
              ExportReport exportRpt =
                  gallerySC.exportSelection(MediaResolution.fromNameOrLabel(format));
              request.setAttribute("ExportReport", exportRpt);
              gallerySC.clearBasket();
              destination = rootDest + "downloadZip.jsp";
            }
          } else {
            destination = rootDest + function;
          }
        } catch (AccessForbiddenException afe) {
          SilverLogger.getLogger(this).warn(afe);
          destination = "/admin/jsp/accessForbidden.jsp";
        } catch (Exception e) {
          request.setAttribute("javax.servlet.jsp.jspException", e);
          destination = "/admin/jsp/errorpageMain.jsp";
        }

        return destination;
      }

      private void setDefaultRequestAttributes(GallerySessionController gallerySC,
          Collection<Media> media, String searchKeyWords, HttpRequest request) {
        request.setAttribute(MEDIA_LIST, media);
        request.setAttribute(NB_MEDIA_PER_PAGE, gallerySC.getNbMediaPerPage());
        request.setAttribute(CURRENT_PAGE_INDEX, gallerySC.getIndexOfCurrentPage());
        request.setAttribute(MEDIA_RESOLUTION, gallerySC.getDisplayedMediaResolution());
        request.setAttribute(IS_VIEW_METADATA, gallerySC.isViewMetadata());
        request.setAttribute(IS_VIEW_LIST, gallerySC.isViewList());
        request.setAttribute(SELECTED_IDS, gallerySC.getListSelected());
        request.setAttribute(IS_BASKET, gallerySC.isBasket());
        request.setAttribute(SEARCH_KEY_WORD, searchKeyWords);
      }

      private String processMediaType(final GallerySessionController gallerySC,
          final HttpRequest request, final String id, final String type) {
        String destination;
        try {
          MediaType mediaType = MediaType.from(type);
          if (mediaType != MediaType.Unknown) {
            // traitement des médias
            request.setAttribute(MEDIA_ID, id);
            destination = getDestination(MEDIA_VIEW_FUNC, gallerySC, request);
          } else if ("Node".equals(type)) {
            // traitement des noeuds = les albums
            destination = getDestination("ViewAlbum", gallerySC, request);
          } else {
            destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
          }
        } catch (Exception e) {
          SilverLogger.getLogger(this).warn(e);
          destination = getDocumentNotFoundDestination(gallerySC, request);
        }
        return destination;
      }

      private String processMedia(final GallerySessionController gallerySC, final HttpRequest request,
          final String rootDest, final SilverpeasRole highestUserRole, final String mediaId) {
        String destination;
        try {
          Media media = gallerySC.getMedia(mediaId);

          request.setAttribute(SEARCH_KEY_WORD, request.getParameter(SEARCH_KEY_WORD));
          request.setAttribute("Rang", gallerySC.getRang());
          request.setAttribute("NbMedia", gallerySC.goToAlbum().getMedia().size());
          request.setAttribute(IS_VIEW_METADATA, gallerySC.isViewMetadata());
          request.setAttribute("IsWatermark", gallerySC.isMakeWatermark());
          request.setAttribute("ImageResolutionPreview", gallerySC.getImageResolutionPreview(media));

          boolean linkDownload = isLinkDownloadable(gallerySC, highestUserRole, media);
          request.setAttribute("ViewLinkDownload", linkDownload);

          putMediaCommonParameters(request, gallerySC, media, highestUserRole);

          // Prepare XML form data
          putXMLDisplayerIntoRequest(media, request, gallerySC);
          // Slideshow requirements
          request.setAttribute(ALBUM_ID, gallerySC.getCurrentAlbumId());
          request.setAttribute("wait", gallerySC.getSlideshowWait());
          // Add this following line for backward compatibility TODO create migration script in
          // order to insert each media inside content manager
          request.setAttribute("SilverObjetId", gallerySC.getSilverObjectId(mediaId));
          // appel jsp
          destination = rootDest + MEDIA_PREFIX + media.getType().toString() + "View.jsp";
        } catch (Exception e) {
          SilverLogger.getLogger(this).warn(e);
          destination = getDocumentNotFoundDestination(gallerySC, request);
        }
        return destination;
      }

      private boolean isLinkDownloadable(final GallerySessionController gallerySC,
          final SilverpeasRole highestUserRole, final Media media) {
        if (gallerySC.getHighestSilverpeasUserRole().isGreaterThanOrEquals(SilverpeasRole.PUBLISHER)) {
          return true;
        }
        return (SilverpeasRole.PRIVILEGED_USER == highestUserRole && media.isDownloadable()) ||
            (SilverpeasRole.WRITER == highestUserRole &&
                media.getCreatorId().equals(gallerySC.getUserId()));
      }

      private Integer getNbOrdersProcess(Collection<Order> orders) {
        int nb = 0;
        for (final Order order : orders) {
          if (isSqlDefined(order.getProcessUserId())) {
            nb++;
          }
        }
        return nb;
      }

      private String createMediaData(HttpRequest request, GallerySessionController gallerySC)
          throws ParseException, PublicationTemplateException {

        final List<FileItem> parameters = request.getFileItems();
        MediaType mediaType = MediaType.from(request.getParameter("type"));
        final MediaDataCreateDelegate delegate =
            new MediaDataCreateDelegate(mediaType, gallerySC.getLanguage(),
                gallerySC.getCurrentAlbumId(), parameters);

        // 1. Getting the header data
        setHeaderData(delegate.getHeaderData(), request);

        String positions = request.getParameter("Positions");
        if (StringUtil.isDefined(positions)) {
          PdcClassificationEntity withClassification = PdcClassificationEntity.fromJSON(positions);
          delegate.getHeaderData().setPdcPositions(withClassification.getPdcPositions());
        }

        // 2. Getting form data
        PublicationTemplate template = gallerySC.getTemplate();
        if (template != null) {
          delegate.setForm(template.getRecordSet(), template.getUpdateForm());
        }

        // Persisting the media in database & on file system
        return gallerySC.createMedia(delegate);
      }

      private void setHeaderData(AbstractMediaDataDelegate.HeaderData headerData,
          HttpRequest request) throws ParseException {
        headerData
            .setHomepageUrl(request.getParameter(ParameterNames.StreamingHomepageUrl));
        headerData.setTitle(request.getParameter(ParameterNames.MediaTitle));
        headerData.setDescription(request.getParameter(ParameterNames.MediaDescription));
        headerData.setAuthor(request.getParameter(ParameterNames.MediaAuthor));
        headerData.setKeyWord(request.getParameter(ParameterNames.MediaKeyWord));
        headerData
            .setBeginVisibilityDate(request.getParameter(ParameterNames.MediaBeginVisibilityDate));
        headerData
            .setEndVisibilityDate(request.getParameter(ParameterNames.MediaEndVisibilityDate));
        headerData
            .setDownloadAuthorized(request.getParameter(ParameterNames.MediaDownloadAuthorized));
        headerData
            .setBeginDownloadDate(request.getParameter(ParameterNames.MediaBeginDownloadDate));
        headerData
            .setEndDownloadDate(request.getParameter(ParameterNames.MediaEndDownloadDate));
      }

      private void updateOrder(HttpServletRequest request, GallerySessionController gallerySC,
          String orderId, String userId) {
        // rechercher la demande
        Order order = gallerySC.getOrder(orderId);

        // mettre à jour la date et le user
        order.setProcessUserId(userId);

        // mettre à jour les lignes
        List<OrderRow> rows = order.getRows();
        for (final OrderRow orderRow : rows) {
          String mediaId = orderRow.getMediaId();
          String download = request.getParameter("DownloadType" + mediaId);
          orderRow.setDownloadDecision(download);
        }
        order.setRows(rows);
        gallerySC.updateOrder(order);

      }

      private void updateSelectedMedia(HttpRequest request, GallerySessionController gallerySC,
          Collection<String> mediaIds, String encoding)
          throws ParseException, PublicationTemplateException {

        // Getting all HTTP parameters
        final List<FileItem> parameters = new ArrayList<>(request.getFileItems());

        final MediaDataUpdateDelegate delegate =
            new MediaDataUpdateDelegate(MediaType.Photo, gallerySC.getLanguage(),
                gallerySC.getCurrentAlbumId(), parameters);

        // Setting header data
        delegate.getHeaderData()
            .setTitle(FileUploadUtil.getParameter(parameters, "Media$Title", null, encoding));
        delegate.getHeaderData().setDescription(
            FileUploadUtil.getParameter(parameters, "Media$Description", null, encoding));
        delegate.getHeaderData()
            .setAuthor(FileUploadUtil.getParameter(parameters, "Media$Author", null, encoding));
        delegate.getHeaderData()
            .setKeyWord(FileUploadUtil.getParameter(parameters, "Media$KeyWord", null, encoding));
        delegate.getHeaderData().setBeginVisibilityDate(
            FileUploadUtil.getParameter(parameters, "Media$BeginVisibilityDate", null, encoding));
        delegate.getHeaderData().setEndVisibilityDate(
            FileUploadUtil.getParameter(parameters, "Media$EndVisibilityDate", null, encoding));
        delegate.getHeaderData().setDownloadAuthorized(
            FileUploadUtil.getParameter(parameters, "Media$DownloadAuthorized", null, encoding));
        delegate.getHeaderData().setBeginDownloadDate(
            FileUploadUtil.getParameter(parameters, "Media$BeginDownloadDate", null, encoding));
        delegate.getHeaderData().setEndDownloadDate(
            FileUploadUtil.getParameter(parameters, "Media$EndDownloadDate", null, encoding));

        // Setting form
        PublicationTemplate template = gallerySC.getTemplate();
        if (template != null) {
          delegate.setForm(template.getRecordSet(), template.getUpdateForm());
        }

        // Process data
        gallerySC.updateMediaByUser(mediaIds, delegate);

        // Reload media of current album
        gallerySC.loadCurrentAlbum();
      }

      private void deleteSelectedMedia(GallerySessionController gallerySC,
          Collection<String> mediaIds) {
        // suppression des médias selectionnés : traitement par lot
        gallerySC.deleteMedia(mediaIds);
      }

      private boolean isDefined(String param) {
        return (param != null && !param.trim().isEmpty());
      }

      private void putXMLDisplayerIntoRequest(Media media, HttpServletRequest request,
          GallerySessionController gallerySC) throws PublicationTemplateException, FormException {
        String mediaId = media.getId();
        PublicationTemplate template = gallerySC.getTemplate();
        if (template != null) {
          RecordSet recordSet = template.getRecordSet();
          DataRecord data = recordSet.getRecord(mediaId);
          if (data != null) {
            request.setAttribute("XMLForm", template.getViewForm());
            request.setAttribute("XMLData", data);
          }
        }
      }

      private void updateMediaData(String mediaId, HttpRequest request,
          GallerySessionController gallerySC) throws ParseException, PublicationTemplateException {

        final MediaDataUpdateDelegate delegate =
            new MediaDataUpdateDelegate(MediaType.Photo, gallerySC.getLanguage(),
                gallerySC.getCurrentAlbumId(), request.getFileItems(), false);

        // 1. Récupération des données de l'entête
        setHeaderData(delegate.getHeaderData(), request);

        // 2. Récupération des données du formulaire
        PublicationTemplate template = gallerySC.getTemplate();
        if (template != null) {
          delegate.setForm(template.getRecordSet(), template.getUpdateForm());
        }

        // Enregistrement des informations des médias
        gallerySC.updateMediaByUser(mediaId, delegate);

        // mise à jour de l'album courant
        Collection<String> albumIds = gallerySC.getAlbumIdsOf(mediaId);
        // regarder si l'album courant est dans la liste des albums
        boolean inAlbum = false;
        boolean first = true;
        String firstAlbumId = "0";
        for (final String albumId : albumIds) {
          if (first) {
            firstAlbumId = albumId;
            first = false;
          }
          if (albumId.equals(gallerySC.getCurrentAlbumId())) {
            inAlbum = true;
          }
        }
        if (!inAlbum) {
          gallerySC.setCurrentAlbumId(firstAlbumId);
        }
      }

      private void putMediaCommonParameters(HttpServletRequest request,
          GallerySessionController gallerySC, Media media, SilverpeasRole userRole) {
        request.setAttribute("Media", media);
        int nbComments = 0;
        try {
          nbComments = gallerySC.getAllComments(media).size();
        } catch (Exception e) {
          SilverLogger.getLogger(this).error(e);
        }
        request.setAttribute("NbComments", nbComments);
        request.setAttribute("Path", gallerySC.getPath());
        request.setAttribute(IS_USE_PDC, gallerySC.isUsePdc());
        request.setAttribute("XMLFormName", gallerySC.getXMLFormName());
        request.setAttribute(IS_BASKET, gallerySC.isBasket());
        request.setAttribute(IS_ORDER, gallerySC.isOrder());

        boolean allowedToUpdateMedia = userRole.isGreaterThanOrEquals(SilverpeasRole.PUBLISHER) ||
            (userRole == SilverpeasRole.WRITER && media.getCreatorId().equals(gallerySC.getUserId()));
        request.setAttribute("UpdateMediaAllowed", allowedToUpdateMedia);

        request.setAttribute("ShowCommentsTab", gallerySC.areCommentsEnabled());
      }

      /**
       * update gallery session controller list of selected elements
       *
       * @param request the incoming request
       * @param gallerySC the session controller of the Gallery application
       */
      private void processSelection(HttpServletRequest request, GallerySessionController gallerySC) {
        String selectedIds = request.getParameter(SELECTED_IDS);
        String notSelectedIds = request.getParameter("NotSelectedIds");
        Collection<String> memSelected = gallerySC.getListSelected();

        if (StringUtil.isDefined(selectedIds)) {
          for (String selectedId : selectedIds.split(",")) {
            if (!memSelected.contains(selectedId)) {
              memSelected.add(selectedId);
            }
          }
        }

        if (StringUtil.isDefined(notSelectedIds)) {
          for (String notSelectedId : notSelectedIds.split(",")) {
            memSelected.remove(notSelectedId);
          }
        }
      }

      private List<String> extractIds(Collection<Media> col) {
        List<String> ids = new ArrayList<>();
        if (col != null) {
          Iterator<Media> it = col.iterator();
          Media media;
          while (it.hasNext()) {
            media = it.next();
            if (media != null) {
              ids.add(media.getId());
            }
          }
        }
        return ids;
      }

      private String returnToAlbum(HttpRequest request, GallerySessionController gallerySC) {
        String destination;
        // retour d'où on vient
        if (!gallerySC.isSearchResult() && !gallerySC.isViewNotVisible()) {
          // retour à l'album en cours
          destination = getDestination(GO_TO_CURRENT_ALBUM_FUNC, gallerySC, request);
        } else {
          // retour aux résultats de recherche ou à la liste des médias non visibles
          if (gallerySC.isViewNotVisible()) {
            destination = getDestination(VIEW_NOT_VISIBLE_FUNC, gallerySC, request);
          } else {
            destination = getDestination(VIEW_SEARCH_RESULTS_FUNC, gallerySC, request);
          }
        }
        return destination;
      }

      private void deselectAll(GallerySessionController gallerySC) {
        gallerySC.setSelect(false);
        gallerySC.clearListSelected();
      }

      private String getDocumentNotFoundDestination(GallerySessionController gallery,
          HttpServletRequest request) {
        request.setAttribute("ComponentId", gallery.getComponentId());
        return "/admin/jsp/documentNotFound.jsp";
      }

    }