Java tutorial
/* * (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.helper; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.SystemUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kitodo.config.ConfigCore; import org.kitodo.config.enums.ParameterCore; import org.kitodo.data.database.beans.Process; import org.kitodo.data.database.beans.Property; import org.kitodo.data.database.beans.Task; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyDocStructHelperInterface; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetadataHelper; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetadataTypeHelper; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetsModsDigitalDocumentHelper; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyPrefsHelper; import org.kitodo.production.services.ServiceManager; import org.kitodo.production.services.data.ProcessService; import org.kitodo.production.services.file.FileService; public class VariableReplacer { private enum MetadataLevel { ALL, FIRSTCHILD, TOPSTRUCT } private static final Logger logger = LogManager.getLogger(VariableReplacer.class); private LegacyMetsModsDigitalDocumentHelper dd; private LegacyPrefsHelper prefs; // $(meta.abc) private static final String NAMESPACE_META = "\\$\\(meta\\.([\\w.-]*)\\)"; private Process process; private Task task; private final FileService fileService = ServiceManager.getFileService(); private final ProcessService processService = ServiceManager.getProcessService(); protected VariableReplacer() { } VariableReplacer(Process process) { this.process = process; } /** * Constructor. * * @param inDigitalDocument * DigitalDocument object * @param inPrefs * Prefs object * @param p * Process object * @param s * Task object */ public VariableReplacer(LegacyMetsModsDigitalDocumentHelper inDigitalDocument, LegacyPrefsHelper inPrefs, Process p, Task s) { this.dd = inDigitalDocument; this.prefs = inPrefs; this.process = p; this.task = s; } /** * Variablen innerhalb eines Strings ersetzen. Dabei vergleichbar zu Ant die * Variablen durchlaufen und aus dem Digital Document holen * * @param inString * to replacement * @return replaced String */ public String replace(String inString) { if (Objects.isNull(inString)) { return ""; } inString = replaceMetadata(inString); // replace paths and files try { // TIFF writer scripts will have a path without an end slash String tifPath = replaceSlashAndSeparator(processService.getImagesTifDirectory(false, this.process.getId(), this.process.getTitle(), this.process.getProcessBaseUri())); String imagePath = replaceSlashAndSeparator(fileService.getImagesDirectory(this.process)); String origPath = replaceSlashAndSeparator( processService.getImagesOriginDirectory(false, this.process)); String processPath = replaceSlashAndSeparator(processService.getProcessDataDirectory(this.process)); String metaFile = replaceSlash(fileService.getMetadataFilePath(this.process, false)); String ocrBasisPath = replaceSlashAndSeparator(fileService.getOcrDirectory(this.process)); String ocrPlaintextPath = replaceSlashAndSeparator(fileService.getTxtDirectory(this.process)); String sourcePath = replaceSlashAndSeparator(fileService.getSourceDirectory(this.process)); String importPath = replaceSlashAndSeparator(fileService.getImportDirectory(this.process)); String prefs = ConfigCore.getParameter(ParameterCore.DIR_RULESETS) + this.process.getRuleset().getFile(); inString = replaceStringAccordingToOS(inString, "(tifurl)", tifPath); inString = replaceStringAccordingToOS(inString, "(origurl)", origPath); inString = replaceStringAccordingToOS(inString, "(imageurl)", imagePath); inString = replaceString(inString, "(tifpath)", tifPath); inString = replaceString(inString, "(origpath)", origPath); inString = replaceString(inString, "(imagepath)", imagePath); inString = replaceString(inString, "(processpath)", processPath); inString = replaceString(inString, "(importpath)", importPath); inString = replaceString(inString, "(sourcepath)", sourcePath); inString = replaceString(inString, "(ocrbasispath)", ocrBasisPath); inString = replaceString(inString, "(ocrplaintextpath)", ocrPlaintextPath); inString = replaceString(inString, "(processtitle)", this.process.getTitle()); inString = replaceString(inString, "(processid)", String.valueOf(this.process.getId().intValue())); inString = replaceString(inString, "(metaFile)", metaFile); inString = replaceString(inString, "(prefs)", prefs); inString = replaceStringForTask(inString); inString = replaceForWorkpieceProperty(inString); inString = replaceForTemplateProperty(inString); inString = replaceForProcessProperty(inString); } catch (IOException e) { logger.error(e.getMessage(), e); } return inString; } /** * Replace metadata, usage: $(meta.firstchild.METADATANAME). * * @param input * String for replacement * @return replaced String */ private String replaceMetadata(String input) { for (MatchResult r : findRegexMatches(NAMESPACE_META, input)) { if (r.group(1).toLowerCase().startsWith("firstchild.")) { input = input.replace(r.group(), getMetadataFromDigitalDocument(MetadataLevel.FIRSTCHILD, r.group(1).substring(11))); } else if (r.group(1).toLowerCase().startsWith("topstruct.")) { input = input.replace(r.group(), getMetadataFromDigitalDocument(MetadataLevel.TOPSTRUCT, r.group(1).substring(10))); } else { input = input.replace(r.group(), getMetadataFromDigitalDocument(MetadataLevel.ALL, r.group(1))); } } return input; } private String replaceSlash(URI directory) { return fileService.getFileName(directory).replace("\\", "/"); } private String replaceSeparator(String input) { if (input.endsWith(File.separator)) { input = input.substring(0, input.length() - File.separator.length()).replace("\\", "/"); } return input; } private String replaceSlashAndSeparator(URI directory) { return replaceSeparator(replaceSlash(directory)); } private String replaceStringAccordingToOS(String input, String condition, String replacer) { if (input.contains(condition)) { if (SystemUtils.IS_OS_WINDOWS) { input = input.replace(condition, "file:/" + replacer); } else { input = input.replace(condition, "file://" + replacer); } } return input; } private String replaceString(String input, String condition, String replacer) { if (input.contains(condition)) { input = input.replace(condition, replacer); } return input; } private String replaceStringForTask(String input) { if (Objects.nonNull(this.task)) { String taskId = String.valueOf(this.task.getId()); String taskName = this.task.getTitle(); input = input.replace("(stepid)", taskId); input = input.replace("(stepname)", taskName); } return input; } /** * Replace WerkstueckEigenschaft, usage: (product.PROPERTYTITLE). * * @param input * String for replacement * @return replaced String */ private String replaceForWorkpieceProperty(String input) { for (MatchResult r : findRegexMatches("\\(product\\.([\\w.-]*)\\)", input)) { String propertyTitle = r.group(1); for (Property workpieceProperty : this.process.getWorkpieces()) { if (workpieceProperty.getTitle().equalsIgnoreCase(propertyTitle)) { input = input.replace(r.group(), workpieceProperty.getValue()); break; } } } return input; } /** * Replace Vorlageeigenschaft, usage: (template.PROPERTYTITLE). * * @param input * String for replacement * @return replaced String */ private String replaceForTemplateProperty(String input) { for (MatchResult r : findRegexMatches("\\(template\\.([\\w.-]*)\\)", input)) { String propertyTitle = r.group(1); for (Property templateProperty : this.process.getTemplates()) { if (templateProperty.getTitle().equalsIgnoreCase(propertyTitle)) { input = input.replace(r.group(), templateProperty.getValue()); break; } } } return input; } /** * Replace Prozesseigenschaft, usage: (process.PROPERTYTITLE). * * @param input * String for replacement * @return replaced String */ private String replaceForProcessProperty(String input) { for (MatchResult r : findRegexMatches("\\(process\\.([\\w.-]*)\\)", input)) { String propertyTitle = r.group(1); List<Property> ppList = this.process.getProperties(); for (Property pe : ppList) { if (pe.getTitle().equalsIgnoreCase(propertyTitle)) { input = input.replace(r.group(), pe.getValue()); break; } } } return input; } /** * Metadatum von FirstChild oder TopStruct ermitteln (vorzugsweise vom * FirstChild) und zurckgeben. */ private String getMetadataFromDigitalDocument(MetadataLevel inLevel, String metadata) { if (Objects.nonNull(this.dd)) { /* TopStruct und FirstChild ermitteln */ LegacyDocStructHelperInterface topstruct = this.dd.getLogicalDocStruct(); LegacyDocStructHelperInterface firstchildstruct = null; if (Objects.nonNull(topstruct.getAllChildren()) && !topstruct.getAllChildren().isEmpty()) { firstchildstruct = topstruct.getAllChildren().get(0); } /* MetadataType ermitteln und ggf. Fehler melden */ LegacyMetadataTypeHelper mdt; try { mdt = LegacyPrefsHelper.getMetadataType(this.prefs, metadata); } catch (IllegalArgumentException e) { Helper.setErrorMessage(e.getLocalizedMessage(), logger, e); return ""; } String resultTop = getMetadataValue(topstruct, mdt); String resultFirst = null; if (Objects.nonNull(firstchildstruct)) { resultFirst = getMetadataValue(firstchildstruct, mdt); } return getResultAccordingToMetadataLevel(inLevel, metadata, resultFirst, resultTop); } else { return ""; } } private String getResultAccordingToMetadataLevel(MetadataLevel metadataLevel, String metadata, String resultFirst, String resultTop) { String result = ""; switch (metadataLevel) { case FIRSTCHILD: // without existing FirstChild, this can not be returned if (Objects.isNull(resultFirst)) { logger.info("Can not replace firstChild-variable for METS: {}", metadata); } else { result = resultFirst; } break; case TOPSTRUCT: if (Objects.isNull(resultTop)) { logger.warn("Can not replace topStruct-variable for METS: {}", metadata); } else { result = resultTop; } break; case ALL: if (Objects.nonNull(resultFirst)) { result = resultFirst; } else if (Objects.nonNull(resultTop)) { result = resultTop; } else { logger.warn("Can not replace variable for METS: {}", metadata); } break; default: break; } return result; } /** * Metadatum von bergebenen Docstruct ermitteln, im Fehlerfall wird null * zurckgegeben. */ private String getMetadataValue(LegacyDocStructHelperInterface inDocstruct, LegacyMetadataTypeHelper mdt) { List<? extends LegacyMetadataHelper> mds = inDocstruct.getAllMetadataByType(mdt); if (!mds.isEmpty()) { return mds.get(0).getValue(); } else { return null; } } /** * Suche nach regulren Ausdrcken in einem String, liefert alle gefundenen * Treffer als Liste zurck. */ private static Iterable<MatchResult> findRegexMatches(String pattern, CharSequence s) { List<MatchResult> results = new ArrayList<>(); for (Matcher m = Pattern.compile(pattern).matcher(s); m.find();) { results.add(m.toMatchResult()); } return results; } }