@Override public String[] unparse(LoadContext context, CDOMObject obj) { Collection<CDOMReference<? extends CDOMList<?>>> changedLists = context.getListContext().getChangedLists(obj, AbilityList.class); Changes<ListKey<ChooseSelectionActor<?>>> actors = context.getObjectContext().getListChanges(obj, ListKey.GA_CAKEYS); Set<String> returnSet = new TreeSet<String>(); TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> m = new TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>>(); TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>> clear = new TripleKeyMapToList< Nature, CDOMSingleRef<AbilityCategory>, List<Prerequisite>, CDOMReference<Ability>>(); Changes<ChooseSelectionActor<?>> listChanges = context.getObjectContext().getListChanges(obj, ListKey.NEW_CHOOSE_ACTOR); Collection<ChooseSelectionActor<?>> listAdded = listChanges.getAdded(); if (listAdded != null && !listAdded.isEmpty()) { for (ChooseSelectionActor<?> csa : listAdded) { if (csa.getSource().equals(getTokenName())) { try { AbilitySelector as = (AbilitySelector) csa; StringBuilder sb = new StringBuilder(); sb.append(as.getAbilityCategory().getLSTformat(false)).append(Constants.PIPE); sb.append(as.getNature()).append(Constants.PIPE); sb.append(as.getLstFormat()); returnSet.add(sb.toString()); } catch (PersistenceLayerException e) { context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage()); return null; } } } } for (CDOMReference ref : changedLists) { AssociatedChanges<CDOMReference<Ability>> changes = context.getListContext().getChangesInList(getTokenName(), obj, ref); if (changes.includesGlobalClear()) { CDOMDirectSingleRef<AbilityList> dr = (CDOMDirectSingleRef<AbilityList>) ref; AbilityList al = dr.get(); StringBuilder sb = new StringBuilder(); sb.append(al.getCategory().getLSTformat(false)).append(Constants.PIPE); sb.append(al.getNature()).append(Constants.PIPE); sb.append(Constants.LST_DOT_CLEAR); returnSet.add(sb.toString()); } MapToList<CDOMReference<Ability>, AssociatedPrereqObject> mtl = changes.getAddedAssociations(); if (mtl != null) { for (CDOMReference<Ability> ab : mtl.getKeySet()) { for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) { Nature nature = assoc.getAssociation(AssociationKey.NATURE); CDOMSingleRef<AbilityCategory> cat = assoc.getAssociation(AssociationKey.CATEGORY); m.addToListFor(nature, cat, assoc.getPrerequisiteList(), ab); } } } mtl = changes.getRemovedAssociations(); if (mtl != null) { for (CDOMReference<Ability> ab : mtl.getKeySet()) { for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) { Nature nature = assoc.getAssociation(AssociationKey.NATURE); CDOMSingleRef<AbilityCategory> cat = assoc.getAssociation(AssociationKey.CATEGORY); clear.addToListFor(nature, cat, assoc.getPrerequisiteList(), ab); } } } } for (Nature nature : m.getKeySet()) { for (CDOMSingleRef<AbilityCategory> category : m.getSecondaryKeySet(nature)) { for (List<Prerequisite> prereqs : m.getTertiaryKeySet(nature, category)) { StringBuilder sb = new StringBuilder(); sb.append(category.getLSTformat(false)).append(Constants.PIPE); sb.append(nature); List<CDOMReference<Ability>> clearList = clear.removeListFor(nature, category, prereqs); if (clearList != null && !clearList.isEmpty()) { sb.append(Constants.PIPE); sb.append(Constants.LST_DOT_CLEAR_DOT); sb.append( ReferenceUtilities.joinLstFormat( clearList, Constants.PIPE + Constants.LST_DOT_CLEAR_DOT)); } sb.append(Constants.PIPE); sb.append( ReferenceUtilities.joinLstFormat( m.getListFor(nature, category, prereqs), Constants.PIPE)); if (prereqs != null && !prereqs.isEmpty()) { sb.append(Constants.PIPE); sb.append(getPrerequisiteString(context, prereqs)); } returnSet.add(sb.toString()); } } } for (Nature nature : clear.getKeySet()) { for (CDOMSingleRef<AbilityCategory> category : clear.getSecondaryKeySet(nature)) { for (List<Prerequisite> prereqs : clear.getTertiaryKeySet(nature, category)) { StringBuilder sb = new StringBuilder(); sb.append(category.getLSTformat(false)).append(Constants.PIPE); sb.append(nature).append(Constants.PIPE).append(Constants.LST_DOT_CLEAR_DOT); sb.append( ReferenceUtilities.joinLstFormat( clear.getListFor(nature, category, prereqs), Constants.PIPE + Constants.LST_DOT_CLEAR_DOT)); if (prereqs != null && !prereqs.isEmpty()) { sb.append(Constants.PIPE); sb.append(getPrerequisiteString(context, prereqs)); } returnSet.add(sb.toString()); } } } Collection<ListKey<ChooseSelectionActor<?>>> addedActors = actors.getAdded(); if (addedActors != null) { for (ListKey<ChooseSelectionActor<?>> lk : addedActors) { Changes<ChooseSelectionActor<?>> cras = context.getObjectContext().getListChanges(obj, lk); for (ChooseSelectionActor<?> cra : cras.getAdded()) { if (getTokenName().equals(cra.getSource())) { try { AbilityTargetSelector ats = (AbilityTargetSelector) cra; StringBuilder sb = new StringBuilder(); sb.append(ats.getAbilityCategory().getLSTformat(false)).append(Constants.PIPE); sb.append(ats.getNature()).append(Constants.PIPE).append(cra.getLstFormat()); List<Prerequisite> prereqs = ats.getPrerequisiteList(); if (prereqs != null && !prereqs.isEmpty()) { sb.append(Constants.PIPE); sb.append(getPrerequisiteString(context, prereqs)); } returnSet.add(sb.toString()); } catch (PersistenceLayerException e) { context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage()); return null; } } } } } if (returnSet.isEmpty()) { return null; } return returnSet.toArray(new String[returnSet.size()]); }
@Override protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) { AbilityCategory category = AbilityCategory.FEAT; Nature nature = Nature.AUTOMATIC; StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); String token = tok.nextToken(); if (looksLikeAPrerequisite(token)) { return new ParseResult.Fail( "Cannot have only PRExxx subtoken in " + getFullName() + ": " + value, context); } ArrayList<PrereqObject> edgeList = new ArrayList<PrereqObject>(); CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(category, nature); boolean first = true; boolean allowPre = true; ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, AbilityCategory.FEAT); while (true) { if (Constants.LST_DOT_CLEAR.equals(token)) { if (!first) { return new ParseResult.Fail( " Non-sensical " + getFullName() + ": .CLEAR was not the first list item: " + value, context); } context.getListContext().removeAllFromList(getFullName(), obj, abilList); allowPre = false; } else if (token.startsWith(Constants.LST_DOT_CLEAR_DOT)) { String clearText = token.substring(7); CDOMReference<Ability> ref = TokenUtilities.getTypeOrPrimitive(rm, clearText); if (ref == null) { return ParseResult.INTERNAL_ERROR; } context.getListContext().removeFromList(getFullName(), obj, abilList, ref); allowPre = false; } else if (Constants.LST_PERCENT_LIST.equals(token)) { ConditionalSelectionActor<AbilitySelection> cca = new ConditionalSelectionActor<AbilitySelection>( new AbilitySelector(SOURCE, AbilityCategory.FEAT, Nature.AUTOMATIC)); edgeList.add(cca); context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, cca); allowPre = false; } else { CDOMReference<Ability> ability = TokenUtilities.getTypeOrPrimitive(rm, token); if (ability == null) { return ParseResult.INTERNAL_ERROR; } ability.setRequiresTarget(true); boolean loadList = true; List<String> choices = null; if (token.indexOf('(') != -1) { choices = new ArrayList<String>(); AbilityUtilities.getUndecoratedName(token, choices); if (choices.size() == 1) { if (Constants.LST_PERCENT_LIST.equals(choices.get(0)) && (ability instanceof CDOMSingleRef)) { CDOMSingleRef<Ability> ref = (CDOMSingleRef<Ability>) ability; AbilityTargetSelector ats = new AbilityTargetSelector(SOURCE, category, ref, nature); context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, ats); edgeList.add(ats); loadList = false; } } } if (loadList) { AssociatedPrereqObject assoc = context.getListContext().addToList(getFullName(), obj, abilList, ability); assoc.setAssociation(AssociationKey.NATURE, nature); assoc.setAssociation(AssociationKey.CATEGORY, category); if (choices != null) { assoc.setAssociation(AssociationKey.ASSOC_CHOICES, choices); } edgeList.add(assoc); } } if (!tok.hasMoreTokens()) { // No prereqs, so we're done return ParseResult.SUCCESS; } first = false; token = tok.nextToken(); if (looksLikeAPrerequisite(token)) { break; } } if (!allowPre) { return new ParseResult.Fail( "Cannot use PREREQs when using .CLEAR, .CLEAR., or %LIST in " + getTokenName(), context); } while (true) { Prerequisite prereq = getPrerequisite(token); if (prereq == null) { return new ParseResult.Fail( " (Did you put feats after the " + "PRExxx tags in " + getFullName() + ":?)", context); } for (PrereqObject edge : edgeList) { edge.addPrerequisite(prereq); } if (!tok.hasMoreTokens()) { break; } token = tok.nextToken(); } return ParseResult.SUCCESS; }
@Override protected ParseResult parseTokenWithSeparator(LoadContext context, CDOMObject obj, String value) { if (obj instanceof Ungranted) { return new ParseResult.Fail( "Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context); } StringTokenizer tok = new StringTokenizer(value, Constants.PIPE); String cat = tok.nextToken(); CDOMSingleRef<AbilityCategory> acRef = context.getReferenceContext().getCDOMReference(ABILITY_CATEGORY_CLASS, cat); if (!tok.hasMoreTokens()) { return new ParseResult.Fail( getTokenName() + " must have a Nature, " + "Format is: CATEGORY|NATURE|AbilityName: " + value, context); } final String natureKey = tok.nextToken(); Nature nature; try { nature = Nature.valueOf(natureKey); } catch (IllegalArgumentException iae) { return new ParseResult.Fail( getTokenName() + " refers to invalid Ability Nature: " + natureKey, context); } if (Nature.ANY.equals(nature)) { return new ParseResult.Fail( getTokenName() + " refers to ANY Ability Nature, cannot be used in " + getTokenName() + ": " + value, context); } if (!tok.hasMoreTokens()) { return new ParseResult.Fail( getTokenName() + " must have abilities, Format is: " + "CATEGORY|NATURE|AbilityName: " + value, context); } String token = tok.nextToken(); if (looksLikeAPrerequisite(token)) { return new ParseResult.Fail( "Cannot have only PRExxx subtoken in " + getTokenName() + ": " + value, context); } String lkString = "GA_CA_" + cat + "_" + natureKey; ListKey glk = ListKey.getKeyFor(ChooseSelectionActor.class, lkString); ListKey<ChooseSelectionActor<?>> lk = glk; ArrayList<PrereqObject> edgeList = new ArrayList<PrereqObject>(); CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(acRef, nature); boolean first = true; boolean removed = false; ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, ABILITY_CATEGORY_CLASS, cat); if (rm == null) { return new ParseResult.Fail( "Could not get Reference Manufacturer for Category: " + cat, context); } boolean prereqsAllowed = true; while (true) { if (Constants.LST_DOT_CLEAR.equals(token)) { if (!first) { return new ParseResult.Fail( " Non-sensical " + getTokenName() + ": .CLEAR was not the first list item: " + value, context); } context.getListContext().removeAllFromList(getTokenName(), obj, abilList); context.getObjectContext().removeFromList(obj, ListKey.GA_CAKEYS, lk); context.getObjectContext().removeList(obj, lk); removed = true; } else if (token.startsWith(Constants.LST_DOT_CLEAR_DOT)) { String clearText = token.substring(7); CDOMReference<Ability> ref = TokenUtilities.getTypeOrPrimitive(rm, clearText); if (ref == null) { return ParseResult.INTERNAL_ERROR; } AssociatedPrereqObject assoc = context.getListContext().removeFromList(getTokenName(), obj, abilList, ref); assoc.setAssociation(AssociationKey.NATURE, nature); assoc.setAssociation(AssociationKey.CATEGORY, acRef); removed = true; } else if (Constants.LST_PERCENT_LIST.equals(token)) { prereqsAllowed = false; AbilitySelector as = new AbilitySelector(getTokenName(), acRef, nature); context.getObjectContext().addToList(obj, ListKey.NEW_CHOOSE_ACTOR, as); } else { CDOMReference<Ability> ability = TokenUtilities.getTypeOrPrimitive(rm, token); if (ability == null) { return ParseResult.INTERNAL_ERROR; } ability.setRequiresTarget(true); boolean loadList = true; List<String> choices = null; if (token.indexOf('(') != -1) { choices = new ArrayList<String>(); AbilityUtilities.getUndecoratedName(token, choices); if (choices.size() == 1) { if (Constants.LST_PERCENT_LIST.equals(choices.get(0)) && (ability instanceof CDOMSingleRef)) { CDOMSingleRef<Ability> ref = (CDOMSingleRef<Ability>) ability; AbilityTargetSelector ats = new AbilityTargetSelector(getTokenName(), acRef, ref, nature); context.getObjectContext().addToList(obj, ListKey.GA_CAKEYS, lk); context.getObjectContext().addToList(obj, lk, ats); edgeList.add(ats); loadList = false; } } } if (loadList) { AssociatedPrereqObject assoc = context.getListContext().addToList(getTokenName(), obj, abilList, ability); assoc.setAssociation(AssociationKey.NATURE, nature); assoc.setAssociation(AssociationKey.CATEGORY, acRef); if (choices != null) { assoc.setAssociation(AssociationKey.ASSOC_CHOICES, choices); } edgeList.add(assoc); } } if (!tok.hasMoreTokens()) { // No prereqs, so we're done return ParseResult.SUCCESS; } first = false; token = tok.nextToken(); if (looksLikeAPrerequisite(token)) { break; } } if (removed || !prereqsAllowed) { return new ParseResult.Fail( "Cannot use PREREQs when using .CLEAR, .CLEAR., or %LIST in " + getTokenName(), context); } while (true) { Prerequisite prereq = getPrerequisite(token); if (prereq == null) { return new ParseResult.Fail( " (Did you put feats after the " + "PRExxx tags in " + getTokenName() + ":?)", context); } for (PrereqObject edge : edgeList) { edge.addPrerequisite(prereq); } if (!tok.hasMoreTokens()) { break; } token = tok.nextToken(); } return ParseResult.SUCCESS; }
@Override public String[] unparse(LoadContext context, CDOMObject obj) { Set<String> returnSet = new TreeSet<String>(); List<String> returnList = new ArrayList<String>(); MapToList<List<Prerequisite>, CDOMReference<Ability>> m = new HashMapToList<List<Prerequisite>, CDOMReference<Ability>>(); AbilityCategory category = AbilityCategory.FEAT; Nature nature = Nature.AUTOMATIC; CDOMReference<AbilityList> abilList = AbilityList.getAbilityListReference(category, nature); AssociatedChanges<CDOMReference<Ability>> changes = context.getListContext().getChangesInList(getFullName(), obj, abilList); Collection<CDOMReference<Ability>> removedItems = changes.getRemoved(); if (changes.includesGlobalClear()) { if (removedItems != null && !removedItems.isEmpty()) { context.addWriteMessage( "Non-sensical relationship in " + getTokenName() + ": global .CLEAR and local .CLEAR. performed"); return null; } returnList.add(Constants.LST_DOT_CLEAR); } else if (removedItems != null && !removedItems.isEmpty()) { returnList.add( Constants.LST_DOT_CLEAR_DOT + ReferenceUtilities.joinLstFormat(removedItems, "|.CLEAR.", true)); } Changes<ChooseSelectionActor<?>> listChanges = context.getObjectContext().getListChanges(obj, ListKey.NEW_CHOOSE_ACTOR); Collection<ChooseSelectionActor<?>> listAdded = listChanges.getAdded(); if (listAdded != null && !listAdded.isEmpty()) { for (ChooseSelectionActor<?> csa : listAdded) { if (csa.getSource().equals(SOURCE)) { try { returnList.add(csa.getLstFormat()); } catch (PersistenceLayerException e) { context.addWriteMessage(getTokenName() + " encountered error: " + e.getMessage()); return null; } } } } MapToList<CDOMReference<Ability>, AssociatedPrereqObject> mtl = changes.getAddedAssociations(); if (mtl != null) { for (CDOMReference<Ability> ab : mtl.getKeySet()) { for (AssociatedPrereqObject assoc : mtl.getListFor(ab)) { m.addToListFor(assoc.getPrerequisiteList(), ab); } } } for (List<Prerequisite> prereqs : m.getKeySet()) { StringBuilder sb = new StringBuilder(); sb.append(ReferenceUtilities.joinLstFormat(m.getListFor(prereqs), Constants.PIPE)); if (prereqs != null && !prereqs.isEmpty()) { sb.append(Constants.PIPE); sb.append(getPrerequisiteString(context, prereqs)); } returnSet.add(sb.toString()); } returnList.addAll(returnSet); return returnList.toArray(new String[returnList.size()]); }