use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.
the class ModifyLst method parseToken.
@Override
public ParseResult parseToken(LoadContext context, CDOMObject obj, String value) {
if (obj instanceof Campaign) {
return new ParseResult.Fail(getTokenName() + " may not be used in Campaign Files. " + "Please use the Global Modifier file", context);
}
ParsingSeparator sep = new ParsingSeparator(value, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + " may not be empty", context);
}
String varName = sep.next();
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + " needed 2nd argument: " + value, context);
}
String modIdentification = sep.next();
if (!sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + " needed third argument: " + value, context);
}
String modInstructions = sep.next();
//Defaults to zero
int priorityNumber = 0;
if (sep.hasNext()) {
String priority = sep.next();
if (priority.length() < 10) {
return new ParseResult.Fail(getTokenName() + " was expecting PRIORITY= but got " + priority + " in " + value, context);
}
if ("PRIORITY=".equalsIgnoreCase(priority.substring(0, 9))) {
try {
priorityNumber = Integer.parseInt(priority.substring(9));
} catch (NumberFormatException e) {
return new ParseResult.Fail(getTokenName() + " requires Priority to be an integer: " + priority.substring(9) + " was not an integer");
}
if (priorityNumber < 0) {
return new ParseResult.Fail(getTokenName() + " Priority requires an integer >= 0. " + priorityNumber + " was not positive");
}
} else {
return new ParseResult.Fail(getTokenName() + " was expecting PRIORITY=x but got " + priority + " in " + value, context);
}
if (sep.hasNext()) {
return new ParseResult.Fail(getTokenName() + " had too many arguments: " + value, context);
}
}
ScopeInstance scopeInst = context.getActiveScope();
LegalScope scope = scopeInst.getLegalScope();
if (!context.getVariableContext().isLegalVariableID(scope, varName)) {
return new ParseResult.Fail(getTokenName() + " found invalid var name: " + varName + "(scope: " + scope.getName() + ") Modified on " + obj.getClass().getSimpleName() + ' ' + obj.getKeyName(), context);
}
FormatManager<?> format = context.getVariableContext().getVariableFormat(scope, varName);
return finishProcessing(context, obj, format, varName, modIdentification, modInstructions, priorityNumber);
}
use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.
the class RemoveFeatToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String value) {
AbilityCategory category = AbilityCategory.FEAT;
Nature nature = Nature.NORMAL;
ParsingSeparator sep = new ParsingSeparator(value, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String activeValue = sep.next();
Formula count;
if (!sep.hasNext()) {
count = FormulaFactory.ONE;
} else {
count = FormulaFactory.getFormulaFor(activeValue);
if (!count.isValid()) {
return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
}
if (!count.isValid()) {
return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
}
if (count.isStatic() && count.resolveStatic().doubleValue() <= 0) {
return new ParseResult.Fail("Count in " + getFullName() + " must be > 0", context);
}
activeValue = sep.next();
}
if (sep.hasNext()) {
return new ParseResult.Fail(getFullName() + " had too many pipe separated items: " + value, context);
}
if (isEmpty(activeValue) || hasIllegalSeparator(',', activeValue)) {
return ParseResult.INTERNAL_ERROR;
}
List<CDOMReference<Ability>> refs = new ArrayList<>();
List<PrimitiveChoiceSet<CNAbilitySelection>> pcs = new ArrayList<>();
ParsingSeparator tok = new ParsingSeparator(activeValue, ',');
tok.addGroupingPair('[', ']');
tok.addGroupingPair('(', ')');
boolean foundAny = false;
boolean foundOther = false;
ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, AbilityCategory.FEAT);
while (tok.hasNext()) {
CDOMReference<Ability> ab = null;
String token = tok.next();
if ("CHOICE".equals(token) || Constants.LST_ANY.equals(token)) {
foundAny = true;
ab = rm.getAllReference();
} else if (token.startsWith(Constants.LST_CLASS_DOT) || token.startsWith(Constants.LST_CLASS_EQUAL)) {
String className = token.substring(6);
if (className.isEmpty()) {
return new ParseResult.Fail(getTokenName() + " must have Class name after " + token, context);
}
CDOMSingleRef<PCClass> pcc = context.getReferenceContext().getCDOMReference(PCCLASS_CLASS, className);
AbilityFromClassChoiceSet acs = new AbilityFromClassChoiceSet(pcc);
pcs.add(acs);
} else {
foundOther = true;
ab = TokenUtilities.getTypeOrPrimitive(rm, token);
if (ab == null) {
return new ParseResult.Fail(" Error was encountered while parsing " + getTokenName() + ": " + value + " had an invalid reference: " + token, context);
}
}
if (ab != null) {
refs.add(ab);
}
}
if (foundAny && foundOther) {
return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
}
if (!refs.isEmpty()) {
AbilityRefChoiceSet rcs = new AbilityRefChoiceSet(CDOMDirectSingleRef.getRef(category), refs, nature);
pcs.add(rcs);
}
if (pcs.isEmpty()) {
return new ParseResult.Fail("Internal Error: " + getFullName() + " did not have any references: " + value, context);
}
PrimitiveChoiceSet<CNAbilitySelection> ascs;
if (pcs.size() == 1) {
ascs = pcs.get(0);
} else {
ascs = new CompoundOrChoiceSet<>(pcs, Constants.COMMA);
}
ChoiceSet<CNAbilitySelection> cs = new ChoiceSet<>(getTokenName(), ascs, true);
cs.setTitle("Select for removal");
PersistentTransitionChoice<CNAbilitySelection> tc = new ConcretePersistentTransitionChoice<>(cs, count);
context.getObjectContext().addToList(obj, ListKey.REMOVE, tc);
tc.allowStack(true);
tc.setChoiceActor(this);
return ParseResult.SUCCESS;
}
use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.
the class Bonus method newBonus.
/**
* Create a new Bonus
* @param context TODO
* @param bonusString
* @return BonusObj
*
* TODO - This is doing all manner of string parsing. It really belongs in
* the persistence layer.
*/
public static BonusObj newBonus(LoadContext context, final String bonusString) {
ParsingSeparator sep = new ParsingSeparator(bonusString, '|');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
if ((bonusString.indexOf(Constants.PIPE) == bonusString.lastIndexOf(Constants.PIPE)) && bonusString.indexOf('%') < 0) {
Logging.errorPrint("Illegal bonus format: " + bonusString);
return null;
}
String bonusName = sep.next();
try {
//Throw away old level value if present
Integer.parseInt(bonusName);
bonusName = sep.next().toUpperCase();
} catch (NumberFormatException exc) {
bonusName = bonusName.toUpperCase();
}
int equalOffset = -1;
Class<? extends BonusObj> bEntry = TokenLibrary.getBonus(bonusName);
String typeOfBonus = bonusName;
if (bEntry == null) {
equalOffset = bonusName.indexOf('=');
if (equalOffset >= 0) {
typeOfBonus = bonusName.substring(0, equalOffset + 1);
bEntry = TokenLibrary.getBonus(typeOfBonus);
}
if (bEntry == null) {
typeOfBonus = Bonus.BONUS_UNDEFINED;
Logging.errorPrint("Unrecognized bonus: " + bonusString);
return null;
}
}
String bonusInfo = sep.next();
String bValue = "0";
if (sep.hasNext()) {
bValue = sep.next();
}
if (bValue.startsWith("PRE") || bValue.startsWith("!PRE")) {
Logging.errorPrint("Invalid BONUS has no value: " + bonusString);
return null;
}
bValue = bValue.toUpperCase();
BonusObj aBonus = null;
try {
aBonus = bEntry.newInstance();
} catch (Exception exc) {
Logging.errorPrint("Could not create bonusObj for:" + bonusString);
return null;
}
aBonus.putOriginalString(bonusString.intern());
aBonus.setBonusName(bonusName.intern());
aBonus.setTypeOfBonus(typeOfBonus.intern());
Formula val = aBonus.setValue(bValue.intern());
if (!val.isValid()) {
Logging.errorPrint("Could not create bonusObj for:" + bonusString + " since Formula " + bValue + " is not valid: " + val.toString());
return null;
}
while (sep.hasNext()) {
final String aString = sep.next().toUpperCase();
if (PreParserFactory.isPreReqString(aString)) {
try {
final PreParserFactory factory = PreParserFactory.getInstance();
aBonus.addPrerequisite(factory.parse(aString));
} catch (PersistenceLayerException ple) {
Logging.errorPrint(ple.getMessage(), ple);
Logging.reportSource(Logging.ERROR, context);
return null;
}
} else if (aString.startsWith("TYPE=") || aString.startsWith("TYPE.")) {
String bonusType = aString.substring(5);
int dotLoc = bonusType.indexOf('.');
if (dotLoc != -1) {
final String stackingFlag = bonusType.substring(dotLoc + 1);
// built into the code.
if (//$NON-NLS-1$
stackingFlag.startsWith("REPLACE")) {
aBonus.setStackingFlag(StackType.REPLACE);
} else if (//$NON-NLS-1$
stackingFlag.startsWith("STACK")) {
aBonus.setStackingFlag(StackType.STACK);
}
}
final boolean result = aBonus.addType(bonusType.intern());
if (!result) {
Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not add type ").append(aString.substring(5)).append(" to bonusType ").append(typeOfBonus).append(" in Bonus.newBonus").toString());
Logging.reportSource(Logging.LST_ERROR, context);
return null;
}
}
}
if (equalOffset >= 0) {
aBonus.setVariable(bonusName.substring(equalOffset + 1).intern());
}
if (!aBonus.requiresRealCaseTarget()) {
bonusInfo = bonusInfo.toUpperCase();
}
StringTokenizer aTok = new StringTokenizer(bonusInfo, ",");
if (!aTok.hasMoreTokens()) {
Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse empty target ").append(" from BONUS:").append(bonusString).toString());
Logging.reportSource(Logging.LST_ERROR, context);
return null;
}
LstUtils.deprecationCheck(aBonus, bonusName, bonusString);
while (aTok.hasMoreTokens()) {
final String token = aTok.nextToken();
final boolean result = aBonus.parseToken(context, token);
if (!result) {
Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse token ").append(token).append(" from BONUS:").append(bonusString).toString());
Logging.reportSource(Logging.LST_ERROR, context);
return null;
}
}
return aBonus;
}
use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.
the class LookupToken method parseToken.
@Override
public ParseResult parseToken(LoadContext context, KitGear kitGear, String value) {
ParsingSeparator sep = new ParsingSeparator(value, ',');
sep.addGroupingPair('[', ']');
sep.addGroupingPair('(', ')');
String first = sep.next();
if (!sep.hasNext()) {
return new ParseResult.Fail("Token must contain separator ','", context);
}
String second = sep.next();
if (sep.hasNext()) {
return new ParseResult.Fail("Token cannot have more than one separator ','", context);
}
Formula formula = FormulaFactory.getFormulaFor(second);
if (!formula.isValid()) {
return new ParseResult.Fail("Formula in " + getTokenName() + " was not valid: " + formula.toString(), context);
}
kitGear.loadLookup(first, formula);
return ParseResult.SUCCESS;
}
use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.
the class OptionToken method parseNonEmptyToken.
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, BaseKit kit, String value) {
ParsingSeparator pipeSep = new ParsingSeparator(value, '|');
pipeSep.addGroupingPair('[', ']');
pipeSep.addGroupingPair('(', ')');
while (pipeSep.hasNext()) {
String subTok = pipeSep.next();
if (subTok.isEmpty()) {
return new ParseResult.Fail(getTokenName() + " arguments has invalid pipe separator: " + value, context);
}
ParseResult pr = checkForIllegalSeparator(',', subTok);
if (!pr.passed()) {
return pr;
}
ParsingSeparator commaSep = new ParsingSeparator(subTok, ',');
commaSep.addGroupingPair('[', ']');
commaSep.addGroupingPair('(', ')');
String minString = commaSep.next();
String maxString;
if (commaSep.hasNext()) {
maxString = commaSep.next();
} else {
maxString = subTok;
}
if (commaSep.hasNext()) {
return new ParseResult.Fail("Token cannot have more than one separator ','", context);
}
Formula min = FormulaFactory.getFormulaFor(minString);
if (!min.isValid()) {
return new ParseResult.Fail("Min Formula in " + getTokenName() + " was not valid: " + min.toString(), context);
}
Formula max = FormulaFactory.getFormulaFor(maxString);
if (!max.isValid()) {
return new ParseResult.Fail("Max Formula in " + getTokenName() + " was not valid: " + max.toString(), context);
}
kit.setOptionBounds(min, max);
}
return ParseResult.SUCCESS;
}
Aggregations