<commit_before>package jfdi.storage.apis;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import jfdi.storage.Constants;
import jfdi.storage.FileManager;
import jfdi.storage.IDatabase;
import jfdi.storage.entities.Alias;
import jfdi.storage.exceptions.DuplicateAliasException;
import jfdi.storage.exceptions.FilePathPair;
import jfdi.storage.exceptions.InvalidAliasException;
import jfdi.storage.serializer.Serializer;

/**
 * This class manages the collection of Aliases persisted in the program
 * storage.
 *
 * @author <NAME>
 *
 */
public class AliasDb implements IDatabase {

    // Singleton instance of AliasDb
    private static AliasDb instance = null;

    // The list of existing and deleted aliases
    private ArrayList<Alias> aliasList = new ArrayList<Alias>();
    private ArrayList<Alias> deletedAliasList = new ArrayList<Alias>();

    // The filepath to the data file
    private Path filePath = null;

    /**
     * This private constructor prevents more instances of AliasDb from being
     * created.
     */
    private AliasDb() {}

    /**
     * This method returns the singleton instance of AliasDb.
     *
     * @return the singleton instance of AliasDb
     */
    public static AliasDb getInstance() {
        if (instance == null) {
            instance = new AliasDb();
        }
        return instance;
    }

    /**
     * This method creates a new alias if the given aliasAttributes is not a
     * duplicate of an existing alias in the database.
     *
     * @param aliasAttributes
     *            the mapping of alias to command that is to be created
     * @throws DuplicateAliasException
     *             if the given alias already exists in the database
     */
    public void create(AliasAttributes aliasAttributes) throws DuplicateAliasException {
        assert aliasAttributes != null;
        if (isDuplicate(aliasAttributes)) {
            throw new DuplicateAliasException(aliasAttributes);
        }
        aliasList.add(aliasAttributes.toEntity());
        persist();
    }

    /**
     * This method returns all the aliases (in the form of their attributes)
     * currently stored in the program's internal state.
     *
     * @return a Collection of AliasAttributes
     */
    public Collection<AliasAttributes> getAll() {
        ArrayList<AliasAttributes> aliasAttributes = new ArrayList<AliasAttributes>();
        for (Alias alias : aliasList) {
            aliasAttributes.add(new AliasAttributes(alias));
        }
        return aliasAttributes;
    }

    /**
     * This method returns the command corresponding to an alias currently
     * stored in the program
     *
     * @param alias
     *            the alias whose command we want to retrieve
     * @return the command if the given alias exists in the program's storage
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public String getCommandFromAlias(String alias) throws InvalidAliasException {
        assert alias != null;
        for (Alias aliasRecord : aliasList) {
            if (aliasRecord.getAlias().equals(alias)) {
                return aliasRecord.getCommand();
            }
        }

        throw new InvalidAliasException(alias);
    }

    /**
     * This method checks if a given alias exists in the database.
     *
     * @param alias
     *            the alias to be checked
     * @return boolean indicating if the alias exists in the database
     */
    public boolean hasAlias(String alias) {
        assert alias != null;
        return aliasList.stream().anyMatch(aliasRecord -> {
            return aliasRecord.getAlias().equals(alias);
        });
    }

    /**
     * This method soft-deletes an existing alias.
     *
     * @param alias
     *            the alias that we want to delete
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public void destroy(String alias) throws InvalidAliasException {
        assert alias != null;
        for (Alias aliasRecord : aliasList) {
            if (aliasRecord.getAlias().equals(alias)) {
                aliasList.remove(aliasRecord);
                deletedAliasList.add(aliasRecord);
                return;
            }
        }
        throw new InvalidAliasException(alias);
    }

    /**
     * This method restores an alias that was soft-deleted earlier.
     *
     * @param alias
     *            the alias that we want to recover
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public void undestroy(String alias) throws InvalidAliasException {
        assert alias != null;
        Alias deletedAlias = null;

        // Start searching from the back to undestroy the latest matching alias
        // if does not already exist
        for (int i = deletedAliasList.size() - 1; i >= 0; i--) {
            deletedAlias = deletedAliasList.get(i);
            if (deletedAlias.getAlias().equals(alias)
                    && !isDuplicate(new AliasAttributes(deletedAlias))) {
                deletedAliasList.remove(i);
                aliasList.add(deletedAlias);
                return;
            }
        }
        throw new InvalidAliasException(alias);
    }

    /**
     * This method checks if the given alias already exists in the program's
     * storage.
     *
     * @param alias
     *            the alias that we want to check
     * @return boolean indicating if the alias already exists
     */
    private boolean isDuplicate(AliasAttributes aliasAttributes) {
        assert aliasAttributes != null;
        String alias = aliasAttributes.getAlias();<commit_msg>Persist alias changes after destroy and undestroy<commit_after>package jfdi.storage.apis;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import jfdi.storage.Constants;
import jfdi.storage.FileManager;
import jfdi.storage.IDatabase;
import jfdi.storage.entities.Alias;
import jfdi.storage.exceptions.DuplicateAliasException;
import jfdi.storage.exceptions.FilePathPair;
import jfdi.storage.exceptions.InvalidAliasException;
import jfdi.storage.serializer.Serializer;

/**
 * This class manages the collection of Aliases persisted in the program
 * storage.
 *
 * @author <NAME>
 *
 */
public class AliasDb implements IDatabase {

    // Singleton instance of AliasDb
    private static AliasDb instance = null;

    // The list of existing and deleted aliases
    private ArrayList<Alias> aliasList = new ArrayList<Alias>();
    private ArrayList<Alias> deletedAliasList = new ArrayList<Alias>();

    // The filepath to the data file
    private Path filePath = null;

    /**
     * This private constructor prevents more instances of AliasDb from being
     * created.
     */
    private AliasDb() {}

    /**
     * This method returns the singleton instance of AliasDb.
     *
     * @return the singleton instance of AliasDb
     */
    public static AliasDb getInstance() {
        if (instance == null) {
            instance = new AliasDb();
        }
        return instance;
    }

    /**
     * This method creates a new alias if the given aliasAttributes is not a
     * duplicate of an existing alias in the database.
     *
     * @param aliasAttributes
     *            the mapping of alias to command that is to be created
     * @throws DuplicateAliasException
     *             if the given alias already exists in the database
     */
    public void create(AliasAttributes aliasAttributes) throws DuplicateAliasException {
        assert aliasAttributes != null;
        if (isDuplicate(aliasAttributes)) {
            throw new DuplicateAliasException(aliasAttributes);
        }
        aliasList.add(aliasAttributes.toEntity());
        persist();
    }

    /**
     * This method returns all the aliases (in the form of their attributes)
     * currently stored in the program's internal state.
     *
     * @return a Collection of AliasAttributes
     */
    public Collection<AliasAttributes> getAll() {
        ArrayList<AliasAttributes> aliasAttributes = new ArrayList<AliasAttributes>();
        for (Alias alias : aliasList) {
            aliasAttributes.add(new AliasAttributes(alias));
        }
        return aliasAttributes;
    }

    /**
     * This method returns the command corresponding to an alias currently
     * stored in the program
     *
     * @param alias
     *            the alias whose command we want to retrieve
     * @return the command if the given alias exists in the program's storage
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public String getCommandFromAlias(String alias) throws InvalidAliasException {
        assert alias != null;
        for (Alias aliasRecord : aliasList) {
            if (aliasRecord.getAlias().equals(alias)) {
                return aliasRecord.getCommand();
            }
        }

        throw new InvalidAliasException(alias);
    }

    /**
     * This method checks if a given alias exists in the database.
     *
     * @param alias
     *            the alias to be checked
     * @return boolean indicating if the alias exists in the database
     */
    public boolean hasAlias(String alias) {
        assert alias != null;
        return aliasList.stream().anyMatch(aliasRecord -> {
            return aliasRecord.getAlias().equals(alias);
        });
    }

    /**
     * This method soft-deletes an existing alias.
     *
     * @param alias
     *            the alias that we want to delete
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public void destroy(String alias) throws InvalidAliasException {
        assert alias != null;
        for (Alias aliasRecord : aliasList) {
            if (aliasRecord.getAlias().equals(alias)) {
                aliasList.remove(aliasRecord);
                deletedAliasList.add(aliasRecord);
                persist();
                return;
            }
        }
        throw new InvalidAliasException(alias);
    }

    /**
     * This method restores an alias that was soft-deleted earlier.
     *
     * @param alias
     *            the alias that we want to recover
     * @throws InvalidAliasException
     *             if the alias does not exist in the database
     */
    public void undestroy(String alias) throws InvalidAliasException {
        assert alias != null;
        Alias deletedAlias = null;

        // Start searching from the back to undestroy the latest matching alias
        // if does not already exist
        for (int i = deletedAliasList.size() - 1; i >= 0; i--) {
            deletedAlias = deletedAliasList.get(i);
            if (deletedAlias.getAlias().equals(alias)
                    && !isDuplicate(new AliasAttributes(deletedAlias))) {
                deletedAliasList.remove(i);
                aliasList.add(deletedAlias);
                persist();
                return;
            }
        }
        throw new InvalidAliasException(alias);
    }

    /**
     * This method checks if the given alias already exists in the program's
     * storage.
     *
     * @param alias
     *            the alias that we want to check
     * @return boolean indicating if the alias already exists
     */
    private boolean isDuplicate(AliasAttributes aliasAttributes) {
        assert aliasAttributes != null;
        String alias = aliasAttributes.getAlias();
{'fraction_non_alphanumeric': 0.07732924544370635, 'fraction_numerical': 0.00034065746891500596, 'mean_word_length': 2.2252128536116453, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '4143299', 'n_tokens_mistral': 2934, 'n_tokens_neox': 2885, 'n_words': 995}