Coverage Summary for Class: TitleGenerator (org.kitodo.production.process)

Class Class, % Method, % Line, %
TitleGenerator 100% (1/1) 100% (7/7) 100% (57/57)


 /*
  * (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.process;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.StringTokenizer;
 
 import org.apache.commons.lang3.StringUtils;
 import org.kitodo.exceptions.ProcessGenerationException;
 import org.kitodo.production.forms.createprocess.ProcessDetail;
 import org.kitodo.production.services.data.ImportService;
 
 public class TitleGenerator extends Generator {
 
     /**
      * Metadata identifier for title doc main.
      */
     public static final String TITLE_DOC_MAIN = "TitleDocMain";
 
     /**
      * Metadata identifier for tsl/ats.
      */
     public static final String TSL_ATS = "TSL_ATS";
 
     /**
      * Constructor for TitleGenerator.
      *
      * @param atstsl                     field used for title generation
      * @param processDetailsList fields used for title generation
      */
     public TitleGenerator(String atstsl, List<ProcessDetail> processDetailsList) {
         super(atstsl, processDetailsList);
     }
 
     /**
      * Generate title for process.
      *
      * @param titleDefinition definition for title to generation
      * @param genericFields   Map of Strings
      * @return String
      */
     public String generateTitle(String titleDefinition, Map<String, String> genericFields)
             throws ProcessGenerationException {
         return generateTitle(titleDefinition, genericFields, getValueOfMetadataID(TITLE_DOC_MAIN, processDetailsList));
     }
 
     /**
      * Generate title for process.
      *
      * @param titleDefinition
      *            definition for title to generation
      * @param genericFields
      *            Map of Strings
      * @return String
      */
     public String generateTitle(String titleDefinition, Map<String, String> genericFields, String title)
             throws ProcessGenerationException {
         String currentAuthors = ImportService.getListOfCreators(this.processDetailsList);
         StringBuilder newTitle = new StringBuilder();
 
         StringTokenizer tokenizer = new StringTokenizer(titleDefinition, "+");
         // parse the band title
         while (tokenizer.hasMoreTokens()) {
             String token = tokenizer.nextToken();
             // if the string begins with ' and ends with ' then take over the content
             if (token.startsWith("'") && token.endsWith("'")) {
                 newTitle.append(token, 1, token.length() - 1);
             } else if (token.startsWith("#")) {
                 // resolve strings beginning with # from generic fields
                 if (Objects.nonNull(genericFields)) {
                     String genericValue = genericFields.get(token);
                     if (Objects.nonNull(genericValue)) {
                         newTitle.append(genericValue);
                     }
                 }
             } else {
                 newTitle.append(evaluateAdditionalDetailsRows(title, currentAuthors, token));
             }
         }
 
         if (newTitle.toString().endsWith("_")) {
             newTitle.setLength(newTitle.length() - 1);
         }
         // remove non-ascii characters for the sake of TIFF header limits
         return newTitle.toString().replaceAll("[^\\p{ASCII}]", "");
     }
 
     /**
      * Forms the author title key, or the title key (4/2/2/1) if no author is
      * given. The author title key is a librarian sort criteria, composed out of
      * the first four letters of the first author’s last name, followed by the
      * first four letters of the title of the works. The title key (4/2/2/1) a
      * librarian sort criteria composed of the title of the works, taking the
      * first four letters of the first word, each the first two letters of the
      * second and third word, and the first letter of the fourth word of the
      * title. Note that this implementation removes non-word characters (any
      * characters except A-Z, such as letters with diacritics).
      *
      * <p>
      * <u>Examples:</u><br>
      * {@code createAtstsl("Twenty Thousand Leagues Under the Sea", "Verne")}:
      * {@code VernTwen}<br>
      * {@code createAtstsl("Oxford English Dictionary", null)}: {@code OxfoEnDi}
      *
      * @param title
      *            the title of the work
      * @param author
      *            the last name of the (first) author, may be {@code null} or
      *            empty
      * @return the author title key, or the title key (4/2/2/1)
      */
     public static String createAtstsl(String title, String author) {
         StringBuilder result = new StringBuilder(8);
         if (Objects.nonNull(author) && !author.trim().isEmpty()) {
             result.append(getPartString(author, 4));
             result.append(getPartString(title, 4));
         } else {
             StringTokenizer titleWords = new StringTokenizer(title);
             int wordNo = 1;
             while (titleWords.hasMoreTokens() && wordNo < 5) {
                 String word = titleWords.nextToken();
                 switch (wordNo) {
                     case 1:
                         result.append(getPartString(word, 4));
                         break;
                     case 2:
                     case 3:
                         result.append(getPartString(word, 2));
                         break;
                     case 4:
                         result.append(getPartString(word, 1));
                         break;
                     default:
                         break;
                 }
                 wordNo++;
             }
         }
         return result.toString().replaceAll("[\\W]", ""); // delete umlauts etc.
     }
 
     /**
      * Get the value of metadata identifier from process details list.
      *
      * @param metadataID
      *            The metadata identifier
      * @param processDetailsList
      *            The process detail list that contains the potential value
      * @return The value of metadata identifier or null
      */
     public static String getValueOfMetadataID(String metadataID, List<ProcessDetail> processDetailsList) {
         for (ProcessDetail row : processDetailsList) {
             String metadata = row.getMetadataID();
             if (Objects.nonNull(metadata) && metadata.equals(metadataID)) {
                 return ImportService.getProcessDetailValue(row);
             }
         }
         return StringUtils.EMPTY;
     }
 
     private String evaluateAdditionalDetailsRows(String currentTitle, String currentAuthors, String token)
             throws ProcessGenerationException {
         StringBuilder newTitle = new StringBuilder();
         for (ProcessDetail row : this.processDetailsList) {
             String rowMetadataID = row.getMetadataID();
             String rowValue = ImportService.getProcessDetailValue(row);
             // if it is the ATS or TSL field, then use the calculated atstsl if it does not already exist
             if (TSL_ATS.equals(rowMetadataID)) {
                 if (StringUtils.isBlank(rowValue)) {
                     rowValue = createAtstsl(currentTitle, currentAuthors);
                 }
                 this.atstsl = rowValue;
             }
             // add the content to the title
             if (rowMetadataID.equals(token) && Objects.nonNull(rowValue)) {
                 newTitle.append(calculateProcessTitleCheck(rowMetadataID, rowValue));
             }
         }
         return newTitle.toString();
     }
 
     private static String getPartString(String word, int length) {
         return word.length() > length ? word.substring(0, length) : word;
     }
 }