<commit_before>/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 01-21-2010
 *
 * @author <NAME>
 * @auther <NAME>
 *
 */
package org.biojava3.core.sequence.loader;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.biojava3.core.sequence.template.SequenceProxyView;
import org.biojava3.core.sequence.template.Compound;
import org.biojava3.core.exceptions.CompoundNotFoundError;
import org.biojava3.core.exceptions.FileAccessError;
import org.biojava3.core.sequence.AccessionID;
import org.biojava3.core.sequence.Strand;

import org.biojava3.core.sequence.io.template.SequenceParserInterface;
import org.biojava3.core.sequence.storage.SequenceAsStringHelper;
import org.biojava3.core.sequence.template.CompoundSet;
import org.biojava3.core.sequence.template.ProxySequenceReader;
import org.biojava3.core.sequence.template.SequenceMixin;
import org.biojava3.core.sequence.template.SequenceView;

/**
 * This class represents the storage container of a sequence stored in a fasta file where
 * the initial parsing of the file we store the offset and length of the sequence. When a call
 * is made to any method that needs sequence data then the file will be opened and the sequence
 * loaded. This class could be improved by using the hints or a some algorithm that indicates
 * the sequence data once loaded should stay loaded. Could keep track of the last time sequence
 * data was loaded and then after X amount of time clear the contents to free up memory.
 *
 *
 * @author <NAME> <<EMAIL>ishf at gmail dot com>
 * @param <C>
 */
public class SequenceFileProxyLoader<C extends Compound> implements ProxySequenceReader<C> {

    SequenceParserInterface sequenceParser;
    private CompoundSet<C> compoundSet;
    private List<C> parsedCompounds = new ArrayList<C>();
    File file;
    long sequenceStartIndex = -1;
    int sequenceLength = -1;
    private boolean initialized = false;

    /**
     *
     * @param file The file where the sequence will be found
     * @param sequenceParser The parser to use to load the sequence
     * @param sequenceStartIndex The file offset to the start of the sequence
     * @param sequenceLength The length of the sequence
     * @param compoundSet
     */
    public SequenceFileProxyLoader(File file, SequenceParserInterface sequenceParser, long sequenceStartIndex, int sequenceLength, CompoundSet<C> compoundSet) {
        this.sequenceParser = sequenceParser;
        this.file = file;
        this.sequenceStartIndex = sequenceStartIndex;
        this.sequenceLength = sequenceLength;
        setCompoundSet(compoundSet);
    }

    /**
     *
     * @param compoundSet
     */
    public void setCompoundSet(CompoundSet<C> compoundSet) {
        this.compoundSet = compoundSet;
    }

    /**
     *  Load the sequence
     * @return
     */
    private boolean init() {
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
            randomAccessFile.seek(sequenceStartIndex);
            String sequence = sequenceParser.getSequence(randomAccessFile, sequenceLength);
            setContents(sequence);
        } catch (Exception e) {
            throw new FileAccessError("Error accessing " + file + " offset=" + sequenceStartIndex + " sequenceLength=" + sequenceLength + " " + e.toString());
        }
        return true;
    }

    /**
     *
     * @param sequence
     */<commit_msg>Fix Bug #3305 for not closing open file<commit_after>/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 01-21-2010
 *
 * @author <NAME>
 * @auther <NAME>
 *
 */
package org.biojava3.core.sequence.loader;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.biojava3.core.sequence.template.SequenceProxyView;
import org.biojava3.core.sequence.template.Compound;
import org.biojava3.core.exceptions.CompoundNotFoundError;
import org.biojava3.core.exceptions.FileAccessError;
import org.biojava3.core.sequence.AccessionID;
import org.biojava3.core.sequence.Strand;

import org.biojava3.core.sequence.io.template.SequenceParserInterface;
import org.biojava3.core.sequence.storage.SequenceAsStringHelper;
import org.biojava3.core.sequence.template.CompoundSet;
import org.biojava3.core.sequence.template.ProxySequenceReader;
import org.biojava3.core.sequence.template.SequenceMixin;
import org.biojava3.core.sequence.template.SequenceView;

/**
 * This class represents the storage container of a sequence stored in a fasta file where
 * the initial parsing of the file we store the offset and length of the sequence. When a call
 * is made to any method that needs sequence data then the file will be opened and the sequence
 * loaded. This class could be improved by using the hints or a some algorithm that indicates
 * the sequence data once loaded should stay loaded. Could keep track of the last time sequence
 * data was loaded and then after X amount of time clear the contents to free up memory.
 *
 *
 * @author <NAME> <<EMAIL>ishf at gmail dot com>
 * @param <C>
 */
public class SequenceFileProxyLoader<C extends Compound> implements ProxySequenceReader<C> {

    SequenceParserInterface sequenceParser;
    private CompoundSet<C> compoundSet;
    private List<C> parsedCompounds = new ArrayList<C>();
    File file;
    long sequenceStartIndex = -1;
    int sequenceLength = -1;
    private boolean initialized = false;

    /**
     *
     * @param file The file where the sequence will be found
     * @param sequenceParser The parser to use to load the sequence
     * @param sequenceStartIndex The file offset to the start of the sequence
     * @param sequenceLength The length of the sequence
     * @param compoundSet
     */
    public SequenceFileProxyLoader(File file, SequenceParserInterface sequenceParser, long sequenceStartIndex, int sequenceLength, CompoundSet<C> compoundSet) {
        this.sequenceParser = sequenceParser;
        this.file = file;
        this.sequenceStartIndex = sequenceStartIndex;
        this.sequenceLength = sequenceLength;
        setCompoundSet(compoundSet);
    }

    /**
     *
     * @param compoundSet
     */
    public void setCompoundSet(CompoundSet<C> compoundSet) {
        this.compoundSet = compoundSet;
    }

    /**
     *  Load the sequence
     * @return
     */
    private boolean init() {
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
            randomAccessFile.seek(sequenceStartIndex);
            String sequence = sequenceParser.getSequence(randomAccessFile, sequenceLength);
            setContents(sequence);
            randomAccessFile.close(); // close file to prevent too many being open
        } catch (Exception e) {
            throw new FileAccessError("Error accessing " + file + " offset=" + sequenceStartIndex + " sequenceLength=" + sequenceLength + " " + e.toString());
        }
        return true;
    }

    /**
     *
     * @param sequence
     */
{'fraction_non_alphanumeric': 0.08275271971641608, 'fraction_numerical': 0.006111722283339445, 'mean_word_length': 3.299527062532843, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1798041', 'n_tokens_mistral': 2233, 'n_tokens_neox': 2180, 'n_words': 746}