package com.lateensoft.pathfinder.toolkit.patching.v6; import android.content.Context; import android.util.Log; import com.lateensoft.pathfinder.toolkit.dao.DataAccessException; import com.lateensoft.pathfinder.toolkit.db.dao.table.*; import com.lateensoft.pathfinder.toolkit.deprecated.v1.PTUserPrefsManager; import com.lateensoft.pathfinder.toolkit.deprecated.v1.db.PTDatabaseManager; import com.lateensoft.pathfinder.toolkit.deprecated.v1.model.character.PTCharacter; import com.lateensoft.pathfinder.toolkit.deprecated.v1.model.party.PTParty; import com.lateensoft.pathfinder.toolkit.deprecated.v1.model.party.PTPartyMember; import com.lateensoft.pathfinder.toolkit.model.NamedList; import com.lateensoft.pathfinder.toolkit.model.character.PathfinderCharacter; import com.lateensoft.pathfinder.toolkit.model.party.Encounter; import com.lateensoft.pathfinder.toolkit.model.party.EncounterParticipant; import com.lateensoft.pathfinder.toolkit.patching.Patch; import com.lateensoft.pathfinder.toolkit.patching.v10.PreV10PartyMember; import com.lateensoft.pathfinder.toolkit.patching.v10.PreV10PartyMemberConverter; import com.lateensoft.pathfinder.toolkit.pref.GlobalPrefs; import com.lateensoft.pathfinder.toolkit.pref.Preferences; import org.jetbrains.annotations.Nullable; import roboguice.RoboGuice; /** * In version 6, the database was overhauled, so old values must be extracted from that database, and migrated * to the new one, using the old deprecated data models. The old database must be deleted once complete. * * ID's in shared preferences were changed from int to long, so those must be deleted and recreated. * * Encounter party in shared preference is now in database * * Delete last tab in shared prefs */ public class PostV5Patch extends Patch { private static final String TAG = PostV5Patch.class.getSimpleName(); private Context appContext; private Preferences preferences; private CharacterModelDAO characterDao; private PartyDAO<Long> partyDao; private EncounterDAO<EncounterParticipant> encounterDao; private PTUserPrefsManager v5Preferences; private PTDatabaseManager v5DBManager; private boolean errorsEncountered = false; public PostV5Patch(Context context) { super(context); appContext = context.getApplicationContext(); preferences = RoboGuice.getInjector(context).getInstance(Preferences.class); characterDao = new CharacterModelDAO(context); PartyMemberIdDAO memberIdDAO = new PartyMemberIdDAO(context); partyDao = new PartyDAO<Long>(context, memberIdDAO); EncounterParticipantDAO participantDao = new EncounterParticipantDAO(context); encounterDao = new EncounterDAO<EncounterParticipant>(context, participantDao); v5Preferences = new PTUserPrefsManager(appContext); v5DBManager = new PTDatabaseManager(appContext); } @Override public boolean apply() { Log.i(TAG, "Applying v5 patches..."); convertCharacters(); convertParties(); convertEncounter(); v5Preferences.remove(PTUserPrefsManager.KEY_SHARED_PREFS_LAST_TAB); appContext.deleteDatabase(PTDatabaseManager.dbName); Log.i(TAG, "v5 patch complete"); return !errorsEncountered; } private void convertCharacters() { int oldSelectedCharacterID = getOldSelectedCharacterId(); // Delete, because need to convert to long later v5Preferences.remove(PTUserPrefsManager.KEY_SHARED_PREFS_SELECTED_CHARACTER); int[] oldCharIDs = v5DBManager.getCharacterIDs(); for (int id : oldCharIDs) { PTCharacter oldChar = v5DBManager.getCharacter(id); PathfinderCharacter newChar = PreV6CharacterConverter.convertCharacter(oldChar); try { characterDao.add(newChar); if (id == oldSelectedCharacterID) { preferences.put(GlobalPrefs.SELECTED_CHARACTER_ID, newChar.getId()); } } catch (DataAccessException e) { errorsEncountered = true; Log.e(TAG, "Error migrating character " + oldChar.getName(), e); } } } private int getOldSelectedCharacterId() { try { return v5Preferences.getSelectedCharacter(); } catch (ClassCastException e) { // Cases in which this has become a long in preferences for unknown reason. return Long.valueOf(preferences.getLong(PTUserPrefsManager.KEY_SHARED_PREFS_SELECTED_CHARACTER, -1)).intValue(); } } private void convertParties() { int oldSelectedPartyID = getOldSelectedPartyId(); // Delete, because need to convert to long later v5Preferences.remove(PTUserPrefsManager.KEY_SHARED_PREFS_SELECTED_PARTY); int[] oldPartyIDs = v5DBManager.getPartyIDs(); for (int id : oldPartyIDs) { PTParty oldParty = v5DBManager.getParty(id); NamedList<PathfinderCharacter> newParty = convertParty(oldParty); try { for (PathfinderCharacter character : newParty) { characterDao.add(character); } long newPartyId = partyDao.add(getPartyWithIdsOnly(newParty)); if (id == oldSelectedPartyID) { preferences.put(GlobalPrefs.SELECTED_PARTY_ID, newPartyId); } } catch (DataAccessException e) { errorsEncountered = true; Log.e(TAG, "Error migrating party " + oldParty.getName(), e); } } } private int getOldSelectedPartyId() { try { return v5Preferences.getSelectedParty(); } catch (ClassCastException e) { return Long.valueOf(preferences.getLong(PTUserPrefsManager.KEY_SHARED_PREFS_SELECTED_PARTY, -1)).intValue(); } } private NamedList<PathfinderCharacter> convertParty(PTParty preV6Party) { NamedList<PathfinderCharacter> newParty = new NamedList<PathfinderCharacter>(preV6Party.getName()); for (int i = 0; i < preV6Party.size(); i++) { PTPartyMember preV6Member = preV6Party.getPartyMember(i); PathfinderCharacter newMember = PreV10PartyMemberConverter.convertPartyMember(convertV6MemberToV10(preV6Member)); newParty.add(newMember); } return newParty; } private PreV10PartyMember convertV6MemberToV10(PTPartyMember deprecatedMember) { PreV10PartyMember preV10PartyMember = new PreV10PartyMember(); preV10PartyMember.name = deprecatedMember.getName(); preV10PartyMember.initiative = deprecatedMember.getInitiative(); preV10PartyMember.AC = deprecatedMember.getAC(); preV10PartyMember.touch = deprecatedMember.getTouch(); preV10PartyMember.flatFooted = deprecatedMember.getFlatFooted(); preV10PartyMember.spellResist = deprecatedMember.getSpellResist(); preV10PartyMember.damageReduction = deprecatedMember.getDamageReduction(); preV10PartyMember.CMD = deprecatedMember.getCMD(); preV10PartyMember.fortSave = deprecatedMember.getFortSave(); preV10PartyMember.reflexSave = deprecatedMember.getReflexSave(); preV10PartyMember.willSave = deprecatedMember.getWillSave(); preV10PartyMember.bluffSkillBonus = deprecatedMember.getBluffSkillBonus(); preV10PartyMember.disguiseSkillBonus = deprecatedMember.getDisguiseSkillBonus(); preV10PartyMember.perceptionSkillBonus = deprecatedMember.getPerceptionSkillBonus(); preV10PartyMember.senseMotiveSkillBonus = deprecatedMember.getSenseMotiveSkillBonus(); preV10PartyMember.stealthSkillBonus = deprecatedMember.getStealthSkillBonus(); preV10PartyMember.lastRolledValue = deprecatedMember.getRolledValue(); return preV10PartyMember; } private NamedList<Long> getPartyWithIdsOnly(NamedList<PathfinderCharacter> modelParty) { NamedList<Long> partyWithMemberIds = new NamedList<Long>(modelParty.getName()); for (PathfinderCharacter character : modelParty) { partyWithMemberIds.add(character.getId()); } return partyWithMemberIds; } private void convertEncounter() { PTParty oldEncounter = v5Preferences.getEncounterParty(); if (oldEncounter != null) { try { Encounter<EncounterParticipant> newEncounter = convertEncounter(oldEncounter); encounterDao.add(newEncounter); preferences.put(GlobalPrefs.SELECTED_ENCOUNTER_ID, newEncounter.getId()); } catch (DataAccessException e) { errorsEncountered = true; Log.e(TAG, "Error migrating encounter party " + oldEncounter.getName(), e); } finally { v5Preferences.remove(PTUserPrefsManager.KEY_SHARED_PREFS_ENCOUNTER_PARTY); } } } private Encounter<EncounterParticipant> convertEncounter(PTParty preV6Party) { Encounter<EncounterParticipant> newEncounter = new Encounter<EncounterParticipant>(preV6Party.getName()); for (int i = 0; i < preV6Party.size(); i++) { PTPartyMember preV6Member = preV6Party.getPartyMember(i); EncounterParticipant newMember = PreV10PartyMemberConverter.convertEncounterParticipant(convertV6MemberToV10(preV6Member)); newEncounter.add(newMember); newMember.setTurnOrder(i); } return newEncounter; } @Nullable @Override public Patch getNext() { return null; } }