All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.softwaremagico.tm.random.predefined.RandomPredefinedFactory Maven / Gradle / Ivy

There is a newer version: 0.10.5
Show newest version
package com.softwaremagico.tm.random.predefined;

/*-
 * #%L
 * Think Machine (Random Generator)
 * %%
 * Copyright (C) 2017 - 2021 Softwaremagico
 * %%
 * This software is designed by Jorge Hortelano Otero. Jorge Hortelano Otero
 *  Valencia (Spain).
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; If not, see .
 * #L%
 */

import com.softwaremagico.tm.Element;
import com.softwaremagico.tm.InvalidXmlElementException;
import com.softwaremagico.tm.XmlFactory;
import com.softwaremagico.tm.character.benefices.AvailableBenefice;
import com.softwaremagico.tm.character.benefices.AvailableBeneficeFactory;
import com.softwaremagico.tm.character.benefices.BeneficeDefinition;
import com.softwaremagico.tm.character.benefices.BeneficeDefinitionFactory;
import com.softwaremagico.tm.character.blessings.Blessing;
import com.softwaremagico.tm.character.blessings.BlessingFactory;
import com.softwaremagico.tm.character.characteristics.Characteristic;
import com.softwaremagico.tm.character.characteristics.CharacteristicName;
import com.softwaremagico.tm.character.characteristics.CharacteristicsDefinitionFactory;
import com.softwaremagico.tm.character.factions.Faction;
import com.softwaremagico.tm.character.factions.FactionsFactory;
import com.softwaremagico.tm.character.occultism.OccultismPath;
import com.softwaremagico.tm.character.occultism.OccultismPathFactory;
import com.softwaremagico.tm.character.races.Race;
import com.softwaremagico.tm.character.races.RaceFactory;
import com.softwaremagico.tm.character.skills.AvailableSkill;
import com.softwaremagico.tm.character.skills.AvailableSkillsFactory;
import com.softwaremagico.tm.language.ITranslator;
import com.softwaremagico.tm.log.MachineLog;
import com.softwaremagico.tm.random.predefined.profile.InvalidRandomPredefinedException;
import com.softwaremagico.tm.random.selectors.IRandomPreference;
import com.softwaremagico.tm.random.selectors.RandomPreferenceUtils;

import java.util.*;
import java.util.stream.Collectors;

public abstract class RandomPredefinedFactory & IRandomPredefined> extends XmlFactory {
    private static final String GROUP = "group";
    private static final String PREFERENCES = "preferences";
    private static final String CHARACTERISTICS_MINIMUM_VALUES = "characteristicsMinimumValues";
    private static final String REQUIRED_SKILLS = "requiredSkills";
    private static final String SUGGESTED_SKILLS = "suggestedSkills";
    private static final String REQUIRED_SKILL = "skill";
    private static final String REQUIRED_SKILLS_ID = "id";
    private static final String REQUIRED_SKILLS_SPECIALIZATION = "speciality";
    private static final String SUGGESTED_BENEFICES = "suggestedBenefices";
    private static final String SUGGESTED_BENEFICES_SPECIALIZATIONS = "suggestedBeneficesSpecialization";
    private static final String MANDATORY_BENEFICES = "mandatoryBenefices";
    private static final String MANDATORY_BENEFICES_SPECIALIZATIONS = "mandatoryBeneficesSpecialization";
    private static final String SUGGESTED_BLESSINGS = "suggestedBlessings";
    private static final String MANDATORY_BLESSINGS = "mandatoryBlessings";
    private static final String MANDATORY_OCCULTISM_PATHS = "mandatoryOccultismPaths";
    private static final String PARENT = "parent";
    private static final String FACTION = "faction";
    private static final String RACE = "race";

    private final Map> predefinedByGroup = new HashMap<>();

    protected void setParent(Predefined predefined, String language, String moduleName)
            throws InvalidXmlElementException {
        final String parentName = getTranslator(moduleName).getNodeValue(predefined.getId(), PARENT);
        if (parentName != null && !parentName.isEmpty()) {
            try {
                final Predefined parent = getElement(parentName, language, moduleName);
                predefined.setParent(parent);
            } catch (Exception e) {
                throw new InvalidRandomPredefinedException("Invalid parent in element '" + predefined + "'.");
            }
        }
    }

    @Override
    public Predefined getElement(String elementId, String language, String moduleName)
            throws InvalidXmlElementException {
        final Predefined randomProfile = super.getElement(elementId, language, moduleName);
        if (!randomProfile.isParentMerged()) {
            setParent(randomProfile, language, moduleName);
        }
        return randomProfile;
    }

    protected abstract Predefined createNew(String id, String name, String description, String language, String moduleName,
                                            Set> randomPreferences, Set characteristicsMinimumValues,
                                            Set requiredSkills, Set suggestedSkills,
                                            Set mandatoryBlessings, Set suggestedBlessings,
                                            Set mandatoryBenefices, Set suggestedBenefices,
                                            Set mandatoryBeneficeSpecializations, Set suggestedBeneficeSpecializations,
                                            Set mandatoryOccultismPaths, Faction faction, Race race, String group);

    private void classify(Predefined predefined, String groupName) {
        predefinedByGroup.computeIfAbsent(groupName, k -> new HashSet<>());
        predefinedByGroup.get(groupName).add(predefined);
    }

    public Set getGroups(boolean nonOfficial, String language, String moduleName) {
        final Set predefinedGroups = getGroups(language, moduleName);
        if (nonOfficial) {
            return predefinedGroups;
        }
        //Remove all non-official groups.
        return predefinedGroups.stream().filter(g -> predefinedByGroup.get(g).stream().anyMatch(Element::isOfficial)).collect(Collectors.toSet());
    }

    public Set getGroups(String language, String moduleName) {
        if (predefinedByGroup.isEmpty()) {
            try {
                getElements(language, moduleName);
            } catch (InvalidXmlElementException e) {
                MachineLog.errorMessage(this.getClass().getName(), e);
            }
        }
        return predefinedByGroup.keySet();
    }

    public void updateGroups(Collection elements) {
        if (predefinedByGroup.isEmpty()) {
            elements.forEach(e -> {
                classify(e, e.getGroup());
            });
        }
    }

    public Set getByGroup(String groupName) {
        return predefinedByGroup.get(groupName);
    }


    @Override
    protected Predefined createElement(ITranslator translator, String predefinedId, String name, String description,
                                       String language, String moduleName)
            throws InvalidXmlElementException {

        final Set> preferencesSelected = new HashSet<>();
        final String preferencesSelectedNames = translator.getNodeValue(predefinedId, PREFERENCES);
        if (preferencesSelectedNames != null) {
            final StringTokenizer preferencesSelectedTokenizer = new StringTokenizer(preferencesSelectedNames, ",");
            while (preferencesSelectedTokenizer.hasMoreTokens()) {
                try {
                    preferencesSelected.add(RandomPreferenceUtils.getSelectedPreference(preferencesSelectedTokenizer
                            .nextToken().trim()));
                } catch (StringIndexOutOfBoundsException e) {
                    throw new InvalidRandomPredefinedException("Invalid preferences '"
                            + preferencesSelectedNames + "' on predefined '" + predefinedId + "'.");
                }
            }
        }

        final Set characteristicsMinimumValues = new HashSet<>();
        for (final CharacteristicName characteristicName : CharacteristicName.values()) {
            final String characteristicValue = translator.getNodeValue(predefinedId, CHARACTERISTICS_MINIMUM_VALUES,
                    characteristicName.name().toLowerCase());
            if (characteristicValue != null) {
                try {
                    final Characteristic characteristicOption = new Characteristic(CharacteristicsDefinitionFactory
                            .getInstance().get(characteristicName, language, moduleName));
                    characteristicOption.setValue(Integer.parseInt(characteristicValue));
                    characteristicsMinimumValues.add(characteristicOption);
                } catch (NumberFormatException e) {
                    throw new InvalidRandomPredefinedException("Invalid min value in characteristic '"
                            + characteristicName.name().toLowerCase() + "' of predefined '" + predefinedId + "'.");
                }
            }
        }

        final Set requiredSkills = new HashSet<>();
        int node = 0;
        while (true) {
            try {
                String requiredSkillId;
                try {
                    requiredSkillId = translator.getNodeValue(predefinedId, REQUIRED_SKILLS, REQUIRED_SKILL,
                            node, REQUIRED_SKILLS_ID);
                    if (requiredSkillId == null) {
                        break;
                    }
                } catch (NullPointerException e) {
                    // Not more.
                    break;
                }
                String skillSpeciality = null;
                try {
                    skillSpeciality = translator.getNodeValue(predefinedId, REQUIRED_SKILLS, REQUIRED_SKILL,
                            node, REQUIRED_SKILLS_SPECIALIZATION);
                } catch (NullPointerException e) {
                    // Not mandatory
                }
                try {
                    if (skillSpeciality == null) {
                        requiredSkills.add(AvailableSkillsFactory.getInstance().getElement(requiredSkillId, language,
                                moduleName));
                    } else {
                        requiredSkills.add(AvailableSkillsFactory.getInstance().getElement(requiredSkillId,
                                skillSpeciality, language, moduleName));
                    }
                } catch (InvalidXmlElementException e) {
                    throw new InvalidRandomPredefinedException("Invalid required skill '" + requiredSkillId + "' for  predefined '"
                            + predefinedId + "'.", e);
                }
                node++;
            } catch (NumberFormatException e) {
                break;
            }
        }

        final Set suggestedSkills = new HashSet<>();
        node = 0;
        while (true) {
            try {
                String suggestedSkillId;
                try {
                    suggestedSkillId = translator.getNodeValue(predefinedId, SUGGESTED_SKILLS, REQUIRED_SKILL,
                            node, REQUIRED_SKILLS_ID);
                    if (suggestedSkillId == null) {
                        break;
                    }
                } catch (NullPointerException e) {
                    // Not more.
                    break;
                }
                String skillSpeciality = null;
                try {
                    skillSpeciality = translator.getNodeValue(predefinedId, SUGGESTED_SKILLS, REQUIRED_SKILL,
                            node, REQUIRED_SKILLS_SPECIALIZATION);
                } catch (NullPointerException e) {
                    // Not mandatory
                }
                try {
                    if (skillSpeciality == null) {
                        suggestedSkills.add(AvailableSkillsFactory.getInstance().getElement(suggestedSkillId, language,
                                moduleName));
                    } else {
                        suggestedSkills.add(AvailableSkillsFactory.getInstance().getElement(suggestedSkillId,
                                skillSpeciality, language, moduleName));
                    }
                } catch (InvalidXmlElementException e) {
                    throw new InvalidRandomPredefinedException("Invalid suggested skill '" + suggestedSkillId
                            + "' for  predefined '" + predefinedId + "'.", e);
                }
                node++;
            } catch (NumberFormatException e) {
                break;
            }
        }

        final Set suggestedBlessings = getCommaSeparatedValues(predefinedId, SUGGESTED_BLESSINGS,
                language, moduleName, BlessingFactory.getInstance());
        final Set mandatoryBlessings = getCommaSeparatedValues(predefinedId, MANDATORY_BLESSINGS,
                language, moduleName, BlessingFactory.getInstance());

        final Set mandatoryBenefices = getCommaSeparatedValues(predefinedId, MANDATORY_BENEFICES,
                language, moduleName, BeneficeDefinitionFactory.getInstance());

        final Set mandatoryBeneficeSpecializations = getCommaSeparatedValues(predefinedId, MANDATORY_BENEFICES_SPECIALIZATIONS,
                language, moduleName, AvailableBeneficeFactory.getInstance());

        final Set suggestedBenefices = getCommaSeparatedValues(predefinedId, SUGGESTED_BENEFICES,
                language, moduleName, BeneficeDefinitionFactory.getInstance());

        final Set suggestedBeneficeSpecializations = getCommaSeparatedValues(predefinedId, SUGGESTED_BENEFICES_SPECIALIZATIONS,
                language, moduleName, AvailableBeneficeFactory.getInstance());

        final Set mandatoryOccultismPaths = getCommaSeparatedValues(predefinedId, MANDATORY_OCCULTISM_PATHS, language,
                moduleName, OccultismPathFactory.getInstance());


        final String group = translator.getNodeValue(predefinedId, GROUP);
        if (group == null) {
            throw new InvalidRandomPredefinedException("Invalid group for '" + predefinedId + "'.");
        }

        final Faction faction = getElement(predefinedId, FACTION, language, moduleName, FactionsFactory.getInstance());

        final Race race = getElement(predefinedId, RACE, language, moduleName, RaceFactory.getInstance());

        final Predefined predefined = createNew(predefinedId, name, description, language, moduleName, preferencesSelected,
                characteristicsMinimumValues, requiredSkills, suggestedSkills, mandatoryBlessings, suggestedBlessings,
                mandatoryBenefices, suggestedBenefices, mandatoryBeneficeSpecializations, suggestedBeneficeSpecializations,
                mandatoryOccultismPaths, faction, race, group);

        classify(predefined, group);

        return predefined;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy