Coverage Summary for Class: ChangeDocStrucTypeDialog (org.kitodo.production.forms.dataeditor)

Class Class, % Method, % Line, %
ChangeDocStrucTypeDialog 100% (1/1) 15,4% (2/13) 6,2% (4/64)


 /*
  * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org>
  *
  * This file is part of the Kitodo project.
  *
  * It is licensed under GNU General Public License version 3 or later.
  *
  * For the full copyright and license information, please read the
  * GPL3-License.txt file that was distributed with this source code.
  */
 
 package org.kitodo.production.forms.dataeditor;
 
 import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 
 import javax.faces.model.SelectItem;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.kitodo.api.dataeditor.rulesetmanagement.StructuralElementViewInterface;
 import org.kitodo.api.dataformat.LogicalDivision;
 import org.kitodo.production.helper.Helper;
 import org.kitodo.production.metadata.MetadataEditor;
 import org.kitodo.production.services.ServiceManager;
 
 /**
  * Backing bean for the change doc struc type dialog of the metadata editor.
  */
 public class ChangeDocStrucTypeDialog {
     private static final Logger logger = LogManager.getLogger(ChangeDocStrucTypeDialog.class);
 
     private final DataEditorForm dataEditor;
     private final List<SelectItem> docStructTypes = new ArrayList<>();
     private String docStructType;
 
     /**
      * Backing bean for the add doc struc type dialog of the metadata editor.
      *
      * @see "WEB-INF/templates/includes/metadataEditor/dialogs/changeDocStrucType.xhtml"
      */
     ChangeDocStrucTypeDialog(DataEditorForm dataEditor) {
         this.dataEditor = dataEditor;
     }
 
     /**
      * Edit the doc struc.
      */
     public void editDocStruc() {
         LogicalDivision selectedStructure = getSelectedLogicalStructure();
         selectedStructure.setType(docStructType);
         dataEditor.refreshStructurePanel();
     }
 
     /**
      * Returns the selected item of the docStructEditTypeSelection drop-down
      * menu.
      *
      * @return the selected item of the docStructEditTypeSelection
      */
     public List<SelectItem> getDocStructTypes() {
         return docStructTypes;
     }
 
     /**
      * Return selected doc struct type.
      *
      * @return selected doc struct type
      */
     public String getDocStructType() {
         return docStructType;
     }
 
     /**
      * Sets the selected item of the docStructEditTypeSelection drop-down menu.
      *
      * @param docStructEditTypeSelectionSelectedItem
      *            selected item to set
      */
     public void setDocStructType(String docStructEditTypeSelectionSelectedItem) {
         this.docStructType = docStructEditTypeSelectionSelectedItem;
     }
 
     /**
      * Prepare popup dialog by retrieving available doc struct types for
      * selected element.
      */
     public void prepare() {
         try {
             LogicalDivision selectedStructure = getSelectedLogicalStructure();
             Map<String, String> possibleTypes = findAllPossibleTypes(selectedStructure);
             docStructTypes.clear();
             for (Entry<String, String> typeOption : possibleTypes.entrySet()) {
                 docStructTypes.add(new SelectItem(typeOption.getKey(), typeOption.getValue()));
             }
             if (!docStructTypes.isEmpty() && !dataEditor.getProcess().getRuleset().isOrderMetadataByRuleset()) {
                 docStructTypes.sort(Comparator.comparing(SelectItem::getLabel));
             }
             docStructType = selectedStructure.getType();
         } catch (IllegalStateException | IOException e) {
             Helper.setErrorMessage(e.getLocalizedMessage(), logger, e);
         }
     }
 
     private LogicalDivision getSelectedLogicalStructure() {
         if (dataEditor.getSelectedStructure().isPresent()) {
             return dataEditor.getSelectedStructure().get();
         } else {
             throw new IllegalStateException("could not retrieve selected structure");
         }
     }
 
     private Map<String, String> findAllPossibleTypes(
             LogicalDivision logicalDivision) throws IOException {
 
         Map<String, String> possibleTypes = getAllowedChildTypesFromIncludedStructuralParentElement(
             logicalDivision);
         restrictTypesToChildElements(logicalDivision, possibleTypes);
         return possibleTypes;
     }
 
     private Map<String, String> getAllowedChildTypesFromIncludedStructuralParentElement(
             LogicalDivision logicalDivision) throws IOException {
 
         LogicalDivision logicalStructure = dataEditor.getWorkpiece().getLogicalStructure();
         if (logicalStructure.equals(logicalDivision)) {
             if (Objects.isNull(dataEditor.getProcess().getParent())) {
                 return dataEditor.getRulesetManagement().getStructuralElements(dataEditor.getPriorityList());
             } else {
                 return getAllowedChildTypesFromParentalProcess();
             }
         } else {
             LinkedList<LogicalDivision> ancestors = MetadataEditor
                     .getAncestorsOfLogicalDivision(logicalDivision, logicalStructure);
             String parentType = ancestors.getLast().getType();
             return getAllowedSubstructuralElements(parentType);
         }
     }
 
     private Map<String, String> getAllowedChildTypesFromParentalProcess() throws IOException {
         URI parentMetadataUri = ServiceManager.getProcessService()
                 .getMetadataFileUri(dataEditor.getProcess().getParent());
         LogicalDivision parentLogicalStructure = ServiceManager.getMetsService().loadWorkpiece(parentMetadataUri)
                 .getLogicalStructure();
         List<LogicalDivision> parentHierarchyPath = MetadataEditor
                 .determineLogicalDivisionPathToChild(parentLogicalStructure,
                     dataEditor.getProcess().getId());
         if (parentHierarchyPath.isEmpty()) {
             throw new IllegalStateException("proces is not linked in parent process");
         }
         return getAllowedSubstructuralElements(
             ((LinkedList<LogicalDivision>) parentHierarchyPath).getLast().getType());
     }
 
     private Map<String, String> getAllowedSubstructuralElements(String parentType) {
         StructuralElementViewInterface parentView = dataEditor.getRulesetManagement().getStructuralElementView(parentType,
             dataEditor.getAcquisitionStage(), dataEditor.getPriorityList());
         return parentView.getAllowedSubstructuralElements();
     }
 
     private void restrictTypesToChildElements(
             LogicalDivision logicalDivision, Map<String, String> possibleTypes) {
         if (logicalDivision.getChildren().isEmpty()) {
             return;
         }
         Set<String> childTypes = new HashSet<>();
         for (LogicalDivision child : logicalDivision.getChildren()) {
             childTypes.add(child.getType());
         }
         for (Iterator<Entry<String, String>> possibleTypesIterator = possibleTypes.entrySet()
                 .iterator(); possibleTypesIterator.hasNext();) {
             String typeToCheck = possibleTypesIterator.next().getKey();
             StructuralElementViewInterface viewOnTypeToCheck = dataEditor.getRulesetManagement().getStructuralElementView(
                 typeToCheck, dataEditor.getAcquisitionStage(), dataEditor.getPriorityList());
             if (!viewOnTypeToCheck.getAllowedSubstructuralElements().keySet().containsAll(childTypes)) {
                 possibleTypesIterator.remove();
             }
         }
     }
 }