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 de.sub.goobi.export.dms; import de.sub.goobi.config.ConfigCore; import de.sub.goobi.config.ConfigProjects; import de.sub.goobi.export.download.ExportMets; import de.sub.goobi.helper.Helper; import de.sub.goobi.helper.tasks.EmptyTask; import de.sub.goobi.helper.tasks.ExportDmsTask; import de.sub.goobi.helper.tasks.TaskManager; import de.sub.goobi.helper.tasks.TaskSitter; import de.sub.goobi.metadaten.MetadatenVerifizierung; import de.sub.goobi.metadaten.copier.CopierData; import de.sub.goobi.metadaten.copier.DataCopier; import java.io.File; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.net.URI; import java.util.ArrayList; import org.apache.commons.configuration.ConfigurationException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Hibernate; import org.kitodo.data.database.beans.Process; import org.kitodo.data.database.beans.User; import org.kitodo.data.database.helper.enums.MetadataFormat; import org.kitodo.services.ServiceManager; import org.kitodo.services.file.FileService; import ugh.dl.DigitalDocument; import ugh.dl.DocStruct; import ugh.dl.Fileformat; import ugh.dl.Metadata; import ugh.exceptions.PreferencesException; import ugh.exceptions.TypeNotAllowedForParentException; import ugh.exceptions.WriteException; import ugh.fileformats.excel.RDFFile; import ugh.fileformats.mets.MetsModsImportExport; public class ExportDms extends ExportMets { private static final Logger logger = LogManager.getLogger(ExportDms.class); ConfigProjects cp; private boolean exportWithImages = true; private boolean exportFullText = true; private final ServiceManager serviceManager = new ServiceManager(); private final FileService fileService = serviceManager.getFileService(); /** * The field exportDmsTask holds an optional task instance. Its progress and * its errors will be passed to the task manager screen (if available) for * visualisation. */ public EmptyTask exportDmsTask = null; public static final String DIRECTORY_SUFFIX = "_tif"; public ExportDms() { } public ExportDms(boolean exportImages) { this.exportWithImages = exportImages; } public void setExportFullText(boolean exportFullText) { this.exportFullText = exportFullText; } /** * DMS-Export an eine gewnschte Stelle. * * @param process * object * @param inZielVerzeichnis * String */ @Override public boolean startExport(Process process, URI inZielVerzeichnis) throws IOException, WriteException, PreferencesException, TypeNotAllowedForParentException { Hibernate.initialize(process.getProject().getProjectFileGroups()); if (process.getProject().isUseDmsImport() && ConfigCore.getBooleanParameter("asynchronousAutomaticExport", false)) { Hibernate.initialize(process.getRuleset()); TaskManager.addTask(new ExportDmsTask(this, process, inZielVerzeichnis)); Helper.setMeldung(TaskSitter.isAutoRunningThreads() ? "DMSExportByThread" : "DMSExportThreadCreated", process.getTitle()); return true; } else { return startExport(process, inZielVerzeichnis, (ExportDmsTask) null); } } /** * The function startExport() performs a DMS export to a desired place. In * addition, it accepts an optional ExportDmsTask object. If that is passed * in, the progress in it will be updated during processing and occurring * errors will be passed to it to be visible in the task manager screen. * * @param process * process to export * @param inZielVerzeichnis * work directory of the user who triggered the export * @param exportDmsTask * ExportDmsTask object to submit progress updates and errors * @return false if an error condition was caught, true otherwise */ public boolean startExport(Process process, URI inZielVerzeichnis, ExportDmsTask exportDmsTask) { this.exportDmsTask = exportDmsTask; try { return startExport(process, inZielVerzeichnis, serviceManager.getProcessService().readMetadataFile(process).getDigitalDocument()); } catch (Exception e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung(Helper.getTranslation("exportError") + process.getTitle(), e); } logger.error("Export abgebrochen, xml-LeseFehler", e); return false; } } /** * Start export. * * @param process * object * @param inZielVerzeichnis * String * @param newFile * DigitalDocument * @return boolean */ public boolean startExport(Process process, URI inZielVerzeichnis, DigitalDocument newFile) throws IOException, WriteException, PreferencesException, TypeNotAllowedForParentException { this.myPrefs = serviceManager.getRulesetService().getPreferences(process.getRuleset()); this.cp = new ConfigProjects(process.getProject().getTitle()); String atsPpnBand = process.getTitle(); /* * Dokument einlesen */ Fileformat gdzfile; try { switch (MetadataFormat.findFileFormatsHelperByName(process.getProject().getFileFormatDmsExport())) { case METS: gdzfile = new MetsModsImportExport(this.myPrefs); break; case METS_AND_RDF: default: gdzfile = new RDFFile(this.myPrefs); break; } gdzfile.setDigitalDocument(newFile); } catch (Exception e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung(Helper.getTranslation("exportError") + process.getTitle(), e); } logger.error("Export abgebrochen, xml-LeseFehler", e); return false; } String rules = ConfigCore.getParameter("copyData.onExport"); if (rules != null && !rules.equals("- keine Konfiguration gefunden -")) { try { new DataCopier(rules).process(new CopierData(gdzfile, process)); } catch (ConfigurationException e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung("dataCopier.syntaxError", e.getMessage()); } return false; } catch (RuntimeException e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung("dataCopier.runtimeException", e.getMessage()); } return false; } } trimAllMetadata(gdzfile.getDigitalDocument().getLogicalDocStruct()); /* * Metadaten validieren */ if (ConfigCore.getBooleanParameter("useMetadatenvalidierung")) { MetadatenVerifizierung mv = new MetadatenVerifizierung(); if (!mv.validate(gdzfile, this.myPrefs, process)) { return false; } } /* * Speicherort vorbereiten und downloaden */ URI zielVerzeichnis; URI userHome; if (process.getProject().isUseDmsImport()) { zielVerzeichnis = URI.create(process.getProject().getDmsImportImagesPath()); userHome = zielVerzeichnis; /* ggf. noch einen Vorgangsordner anlegen */ if (process.getProject().isDmsImportCreateProcessFolder()) { URI userHomeProcess = fileService.createResource(userHome, File.separator + process.getTitle()); zielVerzeichnis = userHomeProcess; /* alte Import-Ordner lschen */ if (!fileService.delete(userHomeProcess)) { Helper.setFehlerMeldung("Export canceled, Process: " + process.getTitle(), "Import folder could not be cleared"); return false; } /* alte Success-Ordner lschen */ File successFile = new File( process.getProject().getDmsImportSuccessPath() + File.separator + process.getTitle()); if (!fileService.delete(successFile.toURI())) { Helper.setFehlerMeldung("Export canceled, Process: " + process.getTitle(), "Success folder could not be cleared"); return false; } /* alte Error-Ordner lschen */ File errorfile = new File( process.getProject().getDmsImportErrorPath() + File.separator + process.getTitle()); if (!fileService.delete(errorfile.toURI())) { Helper.setFehlerMeldung("Export canceled, Process: " + process.getTitle(), "Error folder could not be cleared"); return false; } if (!fileService.fileExist(userHomeProcess)) { fileService.createDirectory(userHome, process.getTitle()); } } } else { zielVerzeichnis = URI.create(inZielVerzeichnis + atsPpnBand + File.separator); // wenn das Home existiert, erst lschen und dann neu anlegen userHome = zielVerzeichnis; if (!fileService.delete(userHome)) { Helper.setFehlerMeldung("Export canceled: " + process.getTitle(), "could not delete home directory"); return false; } prepareUserDirectory(zielVerzeichnis); } if (exportDmsTask != null) { exportDmsTask.setProgress(1); } /* * der eigentliche Download der Images */ try { if (this.exportWithImages) { imageDownload(process, userHome, atsPpnBand, DIRECTORY_SUFFIX); fulltextDownload(process, userHome, atsPpnBand, DIRECTORY_SUFFIX); } else if (this.exportFullText) { fulltextDownload(process, userHome, atsPpnBand, DIRECTORY_SUFFIX); } directoryDownload(process, zielVerzeichnis); } catch (Exception e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung("Export canceled, Process: " + process.getTitle(), e); } return false; } /* * zum Schluss Datei an gewnschten Ort exportieren entweder direkt in * den Import-Ordner oder ins Benutzerhome anschliessend den * Import-Thread starten */ if (process.getProject().isUseDmsImport()) { if (exportDmsTask != null) { exportDmsTask.setWorkDetail(atsPpnBand + ".xml"); } if (MetadataFormat.findFileFormatsHelperByName( process.getProject().getFileFormatDmsExport()) == MetadataFormat.METS) { /* Wenn METS, dann per writeMetsFile schreiben... */ writeMetsFile(process, fileService.createResource(userHome, File.separator + atsPpnBand + ".xml"), gdzfile, false); } else { /* ...wenn nicht, nur ein Fileformat schreiben. */ gdzfile.write(userHome + File.separator + atsPpnBand + ".xml"); } /* ggf. sollen im Export mets und rdf geschrieben werden */ if (MetadataFormat.findFileFormatsHelperByName( process.getProject().getFileFormatDmsExport()) == MetadataFormat.METS_AND_RDF) { writeMetsFile(process, fileService.createResource(userHome, File.separator + atsPpnBand + ".mets.xml"), gdzfile, false); } Helper.setMeldung(null, process.getTitle() + ": ", "DMS-Export started"); if (!ConfigCore.getBooleanParameter("exportWithoutTimeLimit")) { DmsImportThread agoraThread = new DmsImportThread(process, atsPpnBand); agoraThread.start(); try { /* 30 Sekunden auf den Thread warten, evtl. killen */ agoraThread.join(process.getProject().getDmsImportTimeOut().longValue()); if (agoraThread.isAlive()) { agoraThread.stopThread(); } } catch (InterruptedException e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung(process.getTitle() + ": error on export - ", e.getMessage()); } logger.error(process.getTitle() + ": error on export", e); } if (agoraThread.result.length() > 0) { if (exportDmsTask != null) { exportDmsTask .setException(new RuntimeException(process.getTitle() + ": " + agoraThread.result)); } else { Helper.setFehlerMeldung(process.getTitle() + ": ", agoraThread.result); } } else { if (exportDmsTask != null) { exportDmsTask.setProgress(100); } else { Helper.setMeldung(null, process.getTitle() + ": ", "ExportFinished"); } /* Success-Ordner wieder lschen */ if (process.getProject().isDmsImportCreateProcessFolder()) { File successFile = new File(process.getProject().getDmsImportSuccessPath() + File.separator + process.getTitle()); fileService.delete(successFile.toURI()); } } } if (exportDmsTask != null) { exportDmsTask.setProgress(100); } } else { /* ohne Agora-Import die xml-Datei direkt ins Home schreiben */ if (MetadataFormat.findFileFormatsHelperByName( process.getProject().getFileFormatDmsExport()) == MetadataFormat.METS) { writeMetsFile(process, fileService.createResource(zielVerzeichnis, atsPpnBand + ".xml"), gdzfile, false); } else { gdzfile.write(zielVerzeichnis + atsPpnBand + ".xml"); } Helper.setMeldung(null, process.getTitle() + ": ", "ExportFinished"); } return true; } /** * Setter method to pass in a task thread to whom progress and error * messages shall be reported. * * @param task * task implementation */ public void setExportDmsTask(EmptyTask task) { this.exportDmsTask = task; } /** * Run through all metadata and children of given docstruct to trim the * strings calls itself recursively. */ private void trimAllMetadata(DocStruct inStruct) { /* trimm all metadata values */ if (inStruct.getAllMetadata() != null) { for (Metadata md : inStruct.getAllMetadata()) { if (md.getValue() != null) { md.setValue(md.getValue().trim()); } } } /* run through all children of docstruct */ if (inStruct.getAllChildren() != null) { for (DocStruct child : inStruct.getAllChildren()) { trimAllMetadata(child); } } } /** * Download full text. * * @param process * object * @param userHome * File * @param atsPpnBand * String * @param ordnerEndung * String */ public void fulltextDownload(Process process, URI userHome, String atsPpnBand, final String ordnerEndung) throws IOException { // download sources URI sources = serviceManager.getFileService().getSourceDirectory(process); if (fileService.fileExist(sources) && fileService.getSubUris(sources).size() > 0) { URI destination = userHome.resolve(File.separator + atsPpnBand + "_src"); if (!fileService.fileExist(destination)) { fileService.createDirectory(userHome, atsPpnBand + "_src"); } ArrayList<URI> files = fileService.getSubUris(sources); for (URI file : files) { if (fileService.isFile(file)) { if (exportDmsTask != null) { exportDmsTask.setWorkDetail(fileService.getFileName(file)); } URI target = destination.resolve(File.separator + fileService.getFileName(file)); fileService.copyFile(file, target); } } } URI ocr = serviceManager.getFileService().getOcrDirectory(process); if (fileService.fileExist(ocr)) { ArrayList<URI> folder = fileService.getSubUris(ocr); for (URI dir : folder) { if (fileService.isDirectory(dir) && fileService.getSubUris(dir).size() > 0 && fileService.getFileName(dir).contains("_")) { String suffix = fileService.getFileName(dir) .substring(fileService.getFileName(dir).lastIndexOf("_")); URI destination = userHome.resolve(File.separator + atsPpnBand + suffix); if (!fileService.fileExist(destination)) { fileService.createDirectory(userHome, atsPpnBand + suffix); } ArrayList<URI> files = fileService.getSubUris(dir); for (URI file : files) { if (fileService.isFile(file)) { if (exportDmsTask != null) { exportDmsTask.setWorkDetail(fileService.getFileName(file)); } URI target = destination.resolve(File.separator + fileService.getFileName(file)); fileService.copyFile(file, target); } } } } } if (exportDmsTask != null) { exportDmsTask.setWorkDetail(null); } } /** * Download image. * * @param process * object * @param userHome * File * @param atsPpnBand * String * @param ordnerEndung * String */ public void imageDownload(Process process, URI userHome, String atsPpnBand, final String ordnerEndung) throws IOException, InterruptedException { /* * dann den Ausgangspfad ermitteln */ URI tifOrdner = serviceManager.getProcessService().getImagesTifDirectory(true, process); /* * jetzt die Ausgangsordner in die Zielordner kopieren */ if (fileService.fileExist(tifOrdner) && fileService.getSubUris(tifOrdner).size() > 0) { URI zielTif = userHome.resolve(File.separator + atsPpnBand + ordnerEndung); /* bei Agora-Import einfach den Ordner anlegen */ if (process.getProject().isUseDmsImport()) { if (!fileService.fileExist(zielTif)) { fileService.createDirectory(userHome, atsPpnBand + ordnerEndung); } } else { /* * wenn kein Agora-Import, dann den Ordner mit * Benutzerberechtigung neu anlegen */ User myUser = (User) Helper.getManagedBeanValue("#{LoginForm.myBenutzer}"); try { fileService.createDirectoryForUser(zielTif, myUser.getLogin()); } catch (Exception e) { if (exportDmsTask != null) { exportDmsTask.setException(e); } else { Helper.setFehlerMeldung("Export canceled, error", "could not create destination directory"); } logger.error("could not create destination directory", e); if (e instanceof IOException) { throw (IOException) e; } else if (e instanceof InterruptedException) { throw (InterruptedException) e; } else if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { throw new UndeclaredThrowableException(e); } } } /* jetzt den eigentlichen Kopiervorgang */ ArrayList<URI> dateien = fileService.getSubUris(Helper.dataFilter, tifOrdner); for (int i = 0; i < dateien.size(); i++) { if (exportDmsTask != null) { exportDmsTask.setWorkDetail(fileService.getFileName(dateien.get(i))); } URI meinZiel = zielTif.resolve(File.separator + fileService.getFileName(dateien.get(i))); fileService.copyFile(dateien.get(i), meinZiel); if (exportDmsTask != null) { exportDmsTask.setProgress((int) ((i + 1) * 98d / dateien.size() + 1)); if (exportDmsTask.isInterrupted()) { throw new InterruptedException(); } } } if (exportDmsTask != null) { exportDmsTask.setWorkDetail(null); } } } /** * Starts copying all directories configured in kitodo_config.properties * parameter "processDirs" to export folder. * * @param process * object * @param zielVerzeichnis * the destination directory * */ private void directoryDownload(Process process, URI zielVerzeichnis) throws IOException { String[] processDirs = ConfigCore.getStringArrayParameter("processDirs"); for (String processDir : processDirs) { URI srcDir = serviceManager.getProcessService().getProcessDataDirectory(process) .resolve(processDir.replace("(processtitle)", process.getTitle())); URI dstDir = zielVerzeichnis.resolve(processDir.replace("(processtitle)", process.getTitle())); if (fileService.isDirectory(srcDir)) { fileService.copyDirectory(srcDir, dstDir); } } } }