/** * pcgen.core.term.EvaluatorFactory.java * Copyright (c) 2008 Andrew Wilson <nuance@users.sourceforge.net>. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created 03-Oct-2008 17:46:37 * * Current Ver: $Revision:$ * */ package pcgen.core.term; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import pcgen.core.Globals; import pcgen.core.PCStat; import pcgen.util.Logging; public final class EvaluatorFactory { Pattern internalVarPattern; Map<String, TermEvaluatorBuilder> BuilderStore; private Map<String, TermEvaluator> SrcNeutralEvaluatorStore = new HashMap<>(); private Map<String, Map<String, TermEvaluator>> SrcDependantEvaluatorStore = new HashMap<>(); public static final EvaluatorFactory PC = new EvaluatorFactory(true, TermEvaluatorBuilderPCVar.values()); public static final EvaluatorFactory EQ = new EvaluatorFactory(false, TermEvaluatorBuilderEQVar.values()); private EvaluatorFactory ( boolean addStats, final TermEvaluatorBuilder[] termEvaluatorBuilders) { TermEvaluatorBuilder[] evals = (addStats) ? addStatBuilder(termEvaluatorBuilders) : termEvaluatorBuilders; BuilderStore = new TreeMap<>(); StringBuilder sb = new StringBuilder("^("); boolean add = false; for (TermEvaluatorBuilder e : evals) { if (add) { sb.append("|"); } else { add = true; } sb.append(e.getTermConstructorPattern()); String[] keys = e.getTermConstructorKeys(); for (String k : keys) { BuilderStore.put(k, e); } } sb.append(")"); internalVarPattern = Pattern.compile(sb.toString()); } private static TermEvaluatorBuilder[] addStatBuilder( TermEvaluatorBuilder[] builderArray) { int end = builderArray.length; TermEvaluatorBuilder[] tempArray = new TermEvaluatorBuilder[end + 1]; System.arraycopy(builderArray, 0, tempArray, 0, end); tempArray[end] = makeStatBuilder(); return tempArray; } private static TermEvaluatorBuilder makeStatBuilder() { Collection<PCStat> stats = Globals.getContext().getReferenceContext().getConstructedCDOMObjects(PCStat.class); List<String> s = new LinkedList<>(); StringBuilder pSt = new StringBuilder(stats.size() * 4 + 6); pSt.append("(?:"); boolean add1 = false; for (PCStat stat : stats) { if (add1) { pSt.append("|"); } else { add1 = true; } pSt.append(stat.getKeyName()); s.add(stat.getKeyName()); } pSt.append(")"); return new TermEvaluatorBuilderPCStat(pSt.toString(), s.toArray(new String[s.size()]), false); } private TermEvaluator makeTermEvaluator( String term, String source) { Matcher mat = internalVarPattern.matcher(term); if (mat.find()) { String matchedPortion = mat.group(1); TermEvaluatorBuilder f = BuilderStore.get(matchedPortion); try { if (f.isEntireTerm() && (term.length() != matchedPortion.length())) { return null; } else { return f.getTermEvaluator(term, source, matchedPortion); } } catch (TermEvaulatorException e) { if (Logging.isDebugMode()) { Logging.log(Logging.DEBUG, e.toString()); } } } return null; } public TermEvaluator getTermEvaluator ( String term, String source) { Map<String, TermEvaluator> inner = SrcDependantEvaluatorStore.get(term); if (inner == null) { TermEvaluator evaluator = SrcNeutralEvaluatorStore.get(term); if (evaluator != null) { return evaluator; } } else { TermEvaluator evaluator = inner.get(source); if (evaluator != null) { return evaluator; } } TermEvaluator evaluator = makeTermEvaluator(term, source); if (evaluator == null) { return null; } if (evaluator.isSourceDependant()) { Map<String, TermEvaluator> i = SrcDependantEvaluatorStore.get(term); Map<String, TermEvaluator> j = (i == null) ? new HashMap<>() : i; j.put(source, evaluator); SrcDependantEvaluatorStore.put(term, j); } else { SrcNeutralEvaluatorStore.put(term, evaluator); } return evaluator; } }