blob: 9ba0bf29109d41dde941201a3983975841b02dfa [file] [log] [blame]
/*********************************************************************************************************************
* Copyright (c) 2008, 2013 Empolis Information Management GmbH and brox IT Solutions GmbH. All rights reserved.
* This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
*********************************************************************************************************************/
package org.eclipse.smila.importing.compounds.compress;
import static org.eclipse.smila.importing.compounds.compress.CommonsCompressCompoundExtractorService.KEY_TMP_FILE_NAME;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.smila.datamodel.Record;
/**
* Iterator on given record list, that attaches an attachment from a file in tmpDir. Name of attachment file must be
* stored in each record as attribute {@link CommonsCompressCompoundExtractorService#KEY_TMP_FILE_NAME}. The records are
* removed from the list after returned by next() in order to save memory.
*/
public final class AttachmentSettingIterator implements Iterator<Record> {
/** log. */
private final Log _log = LogFactory.getLog(CommonsCompressCompoundExtractorService.class);
private final String _contentAttachmentName;
private final List<Record> _records;
private final Path _tmpDir;
private int _index;
/**
* create instance.
*
* @param records
* list of records
* @param contentAttachmentName
* name of attachment to use
* @param tmpDir
* directory in which the attachment files are stored.
*/
public AttachmentSettingIterator(final List<Record> records, final String contentAttachmentName, final Path tmpDir) {
_contentAttachmentName = contentAttachmentName;
_records = records;
_tmpDir = tmpDir;
}
/** {@inheritDoc} */
@Override
public boolean hasNext() {
return _index < _records.size();
}
/** {@inheritDoc} */
@Override
public Record next() {
final Record record = _records.set(_index, null);
_index++;
if (record != null && record.getMetadata().containsKey(KEY_TMP_FILE_NAME)) {
final File file = new File(record.getMetadata().getStringValue(KEY_TMP_FILE_NAME));
try {
record.setAttachment(_contentAttachmentName, FileUtils.readFileToByteArray(file));
} catch (final IOException e) {
_log.warn("Cannot access temporary extracted file '" + file.getAbsolutePath() + "'.", e);
}
if (!file.delete()) {
file.deleteOnExit();
}
}
if (!hasNext()) {
try {
FileUtils.deleteDirectory(_tmpDir.toFile());
} catch (final IOException e) {
_log.warn("Could not remove temporary directory '" + _tmpDir.toAbsolutePath().toString() + "'.");
}
}
return record;
}
/**
* {@inheritDoc}. Yes, I know what you're thinking. And you're right. But the files should be discarded... At least if
* we have the chance to do so. On system start the rest is eliminated (e.g. if the JRE had been killed or the files
* could not be deleted, etc.)
*/
@Override
protected void finalize() {
try {
if (hasNext()) {
FileUtils.deleteDirectory(_tmpDir.toFile());
}
} catch (final IOException e) {
_log.warn("Could not remove temporary directory '" + _tmpDir.toAbsolutePath().toString() + "'.");
}
try {
super.finalize();
} catch (final Throwable t) {
_log.warn("Error while cleaning up iterator. ", t);
}
}
/** {@inheritDoc} */
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}