/**
* Gui2InfoFactory.java
* Copyright James Dempsey, 2010
*
* 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 on 07/02/2011 7:13:32 PM
*
* $Id$
*/
package pcgen.gui2.facade;
import java.io.File;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
import pcgen.base.formula.Formula;
import pcgen.base.lang.StringUtil;
import pcgen.base.util.Indirect;
import pcgen.cdom.base.CDOMObject;
import pcgen.cdom.base.CDOMReference;
import pcgen.cdom.base.ChooseInformation;
import pcgen.cdom.base.Constants;
import pcgen.cdom.content.CNAbility;
import pcgen.cdom.content.CNAbilityFactory;
import pcgen.cdom.content.HitDie;
import pcgen.cdom.content.LevelCommandFactory;
import pcgen.cdom.content.fact.FactDefinition;
import pcgen.cdom.content.factset.FactSetDefinition;
import pcgen.cdom.enumeration.AspectName;
import pcgen.cdom.enumeration.FactKey;
import pcgen.cdom.enumeration.FactSetKey;
import pcgen.cdom.enumeration.FormulaKey;
import pcgen.cdom.enumeration.IntegerKey;
import pcgen.cdom.enumeration.ListKey;
import pcgen.cdom.enumeration.MapKey;
import pcgen.cdom.enumeration.Nature;
import pcgen.cdom.enumeration.ObjectKey;
import pcgen.cdom.enumeration.RaceSubType;
import pcgen.cdom.enumeration.RaceType;
import pcgen.cdom.enumeration.SourceFormat;
import pcgen.cdom.enumeration.StringKey;
import pcgen.cdom.helper.Aspect;
import pcgen.cdom.reference.ReferenceUtilities;
import pcgen.cdom.util.CControl;
import pcgen.cdom.util.ControlUtilities;
import pcgen.core.Ability;
import pcgen.core.BenefitFormatting;
import pcgen.core.BonusManager.TempBonusInfo;
import pcgen.core.Deity;
import pcgen.core.Domain;
import pcgen.core.Equipment;
import pcgen.core.EquipmentModifier;
import pcgen.core.Globals;
import pcgen.core.Kit;
import pcgen.core.Movement;
import pcgen.core.PCClass;
import pcgen.core.PCStat;
import pcgen.core.PCTemplate;
import pcgen.core.PlayerCharacter;
import pcgen.core.Race;
import pcgen.core.SettingsHandler;
import pcgen.core.Skill;
import pcgen.core.SpecialProperty;
import pcgen.core.SubClass;
import pcgen.core.WeaponProf;
import pcgen.core.analysis.BonusCalc;
import pcgen.core.analysis.OutputNameFormatting;
import pcgen.core.analysis.SkillInfoUtilities;
import pcgen.core.bonus.BonusObj;
import pcgen.core.character.CharacterSpell;
import pcgen.core.character.SpellBook;
import pcgen.core.character.SpellInfo;
import pcgen.core.character.WieldCategory;
import pcgen.core.display.CharacterDisplay;
import pcgen.core.display.DescriptionFormatting;
import pcgen.core.display.SkillCostDisplay;
import pcgen.core.display.TemplateModifier;
import pcgen.core.display.VisionDisplay;
import pcgen.core.kit.BaseKit;
import pcgen.core.prereq.PrerequisiteUtilities;
import pcgen.core.spell.Spell;
import pcgen.facade.core.AbilityFacade;
import pcgen.facade.core.ClassFacade;
import pcgen.facade.core.DeityFacade;
import pcgen.facade.core.DomainFacade;
import pcgen.facade.core.EquipModFacade;
import pcgen.facade.core.EquipmentFacade;
import pcgen.facade.core.InfoFacade;
import pcgen.facade.core.InfoFactory;
import pcgen.facade.core.KitFacade;
import pcgen.facade.core.RaceFacade;
import pcgen.facade.core.SkillFacade;
import pcgen.facade.core.SpellFacade;
import pcgen.facade.core.TempBonusFacade;
import pcgen.facade.core.TemplateFacade;
import pcgen.gui2.util.HtmlInfoBuilder;
import pcgen.io.exporttoken.EqToken;
import pcgen.io.exporttoken.WeaponToken;
import pcgen.rules.context.LoadContext;
import pcgen.system.LanguageBundle;
import pcgen.system.PCGenSettings;
import pcgen.util.Delta;
import pcgen.util.Logging;
import pcgen.util.enumeration.Tab;
import pcgen.util.enumeration.View;
/**
* The Class <code>Gui2InfoFactory</code> provides character related information
* on various facade objects. The information is displayed to the user via the
* new user interface.
*
* <br>
*
* @author James Dempsey <jdempsey@users.sourceforge.net>
*/
public class Gui2InfoFactory implements InfoFactory
{
/** A default return value for an invalid request. */
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static NumberFormat ADJ_FMT = new DecimalFormat("+0;-0"); //$NON-NLS-1$
private static NumberFormat COST_FMT = new DecimalFormat("#,##0.##"); //$NON-NLS-1$
/** Constant for 2 spaces in HTML */
private static final String TWO_SPACES = " "; //$NON-NLS-1$
/** Constant for HTML bold start tag */
private static final String BOLD = "<b>"; //$NON-NLS-1$
/** Constant for HTML bold end tag */
private static final String END_BOLD = "</b>"; //$NON-NLS-1$
private final PlayerCharacter pc;
private final CharacterDisplay charDisplay;
/**
* Create a new Gui2InfoFactory instance for the character.
* @param pc The character
*/
public Gui2InfoFactory(PlayerCharacter pc)
{
this.pc = pc;
this.charDisplay = pc == null ? null : pc.getDisplay();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getFavoredClass(pcgen.core.facade.RaceFacade)
*/
@Override
public String getFavoredClass(RaceFacade race)
{
if (!(race instanceof Race))
{
return Gui2InfoFactory.EMPTY_STRING;
}
String[] favClass =
Globals.getContext().unparseSubtoken(race, "FAVCLASS");
return StringUtil.join(favClass, ", ");
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.RaceFacade)
*/
@Override
public String getHTMLInfo(RaceFacade raceFacade)
{
if (!(raceFacade instanceof Race))
{
return EMPTY_STRING;
}
Race race = (Race) raceFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
if (!race.getKeyName().startsWith("<none"))
{
infoText.appendTitleElement(OutputNameFormatting.piString(race, false));
infoText.appendLineBreak();
RaceType rt = race.get(ObjectKey.RACETYPE);
if (rt != null)
{
infoText.appendI18nElement("in_irInfoRaceType", rt.toString()); //$NON-NLS-1$
}
List<RaceSubType> rst = race.getListFor(ListKey.RACESUBTYPE);
if (rst != null)
{
infoText.appendSpacer();
infoText.appendI18nElement("in_irInfoSubType", StringUtil.join(rst, ", ")); //$NON-NLS-1$
}
if (!race.getType().isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nElement("in_irInfoType", race.getType()); //$NON-NLS-1$
}
appendFacts(infoText, race);
infoText.appendLineBreak();
String size = race.getSize();
if (StringUtils.isNotEmpty(size))
{
infoText.appendI18nElement("in_size", size); //$NON-NLS-1$
}
String movement = getMovement(raceFacade);
if (!movement.isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nElement("in_movement", movement); //$NON-NLS-1$
}
String vision = getVision(raceFacade);
if (!vision.isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nElement("in_vision", vision); //$NON-NLS-1$
}
String bString = PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
race.getPrerequisiteList(), false);
if (!bString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_requirements", bString); //$NON-NLS-1$
}
String desc = pc.getDescription(race);
if (!desc.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(race, desc, false));
}
String statAdjustments = getStatAdjustments(raceFacade);
if (StringUtils.isNotEmpty(statAdjustments))
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_irTableStat", statAdjustments); //$NON-NLS-1$
}
LevelCommandFactory levelCommandFactory = race.get(ObjectKey.MONSTER_CLASS);
if (levelCommandFactory != null)
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_irInfoMonsterClass", //$NON-NLS-1$
String.valueOf(levelCommandFactory.getLevelCount()),
OutputNameFormatting.piString(levelCommandFactory.getPCClass(), false));
}
String favoredClass = getFavoredClass(raceFacade);
if (StringUtils.isNotEmpty(favoredClass))
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_favoredClass", favoredClass); //$NON-NLS-1$
}
bString = race.getSource();
if (!bString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_sourceLabel", bString); //$NON-NLS-1$
}
}
return infoText.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.ClassFacade, pcgen.core.facade.ClassFacade)
*/
@Override
public String getHTMLInfo(ClassFacade classFacade,
ClassFacade parentClassFacade)
{
if (!(classFacade instanceof PCClass))
{
return EMPTY_STRING;
}
PCClass aClass = (PCClass) classFacade;
PCClass parentClass = aClass;
String aString;
boolean isSubClass = aClass instanceof SubClass;
if (isSubClass && parentClassFacade != null)
{
parentClass = (PCClass) parentClassFacade;
}
final HtmlInfoBuilder b =
new HtmlInfoBuilder(OutputNameFormatting
.piString(aClass, false));
b.appendLineBreak();
// Subclass cost - at the top to make choices easier
if (isSubClass && aClass.getSafe(IntegerKey.COST) != 0)
{
b.appendI18nElement("in_clInfoCost", String.valueOf(aClass.getSafe(IntegerKey.COST))); //$NON-NLS-1$
b.appendLineBreak();
}
// Type
aString = aClass.getType();
if (isSubClass && (aString.isEmpty()))
{
aString = parentClass.getType();
}
b.appendI18nElement("in_clInfoType", aString); //$NON-NLS-1$
// Hit Die
HitDie hitDie = aClass.getSafe(ObjectKey.LEVEL_HITDIE);
if (isSubClass && HitDie.ZERO.equals(hitDie))
{
hitDie = parentClass.getSafe(ObjectKey.LEVEL_HITDIE);
}
if (!HitDie.ZERO.equals(hitDie))
{
b.appendSpacer();
b.appendI18nElement("in_clInfoHD", "d" + hitDie.getDie()); //$NON-NLS-1$ //$NON-NLS-2$
}
appendFacts(b, aClass);
if (SettingsHandler.getGame().getTabShown(Tab.SPELLS))
{
FactKey<String> fk = FactKey.valueOf("SpellType");
aString = aClass.getResolved(fk);
if (isSubClass && aString == null)
{
aString = parentClass.getSpellType();
}
b.appendSpacer();
b.appendI18nElement("in_clInfoSpellType", aString); //$NON-NLS-1$
aString = aClass.getSpellBaseStat();
/*
* CONSIDER This test here is the ONLY place where the "magical"
* value of null is tested for in getSpellBaseStat(). This is
* currently set by SubClass and SubstititionClass, so it IS
* used, but the question is: Is there a better method for
* identifying this special deferral to the "parentClass" other
* than null SpellBaseStat? - thpr 11/9/06
*/
if (isSubClass && ((aString == null) || (aString.isEmpty())))
{
aString = parentClass.getSpellBaseStat();
}
b.appendSpacer();
b.appendI18nElement("in_clInfoBaseStat", aString); //$NON-NLS-1$
}
// Prereqs
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null, aClass
.getPrerequisiteList(), false);
if (isSubClass && (aString.isEmpty()))
{
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
parentClass.getPrerequisiteList(), false);
}
if (!aString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_requirements", aString); //$NON-NLS-1$
}
//Description
String desc = pc.getDescription(aClass);
if (!desc.isEmpty())
{
b.appendLineBreak();
b.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(aClass, desc, false));
}
// Sub class extra info
if (isSubClass)
{
int specialtySpells = aClass.getSafe(IntegerKey.KNOWN_SPELLS_FROM_SPECIALTY);
b.appendLineBreak();
b.appendI18nElement("in_clSpecialtySpells", Delta.toString(specialtySpells)); //$NON-NLS-1$
b.appendSpacer();
b.appendI18nElement("in_clSpecialty", ((SubClass) aClass).getChoice()); //$NON-NLS-1$
}
// Source
aString = aClass.getSource();
if (isSubClass && (aString.isEmpty()))
{
aString = parentClass.getSource();
}
if (!aString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_source", aString); //$NON-NLS-1$
}
return b.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.SkillFacade)
*/
@Override
public String getHTMLInfo(SkillFacade skillFacade)
{
if (!(skillFacade instanceof Skill))
{
return EMPTY_STRING;
}
Skill skill = (Skill) skillFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(OutputNameFormatting.piString(skill, false));
infoText.appendLineBreak();
String typeString = StringUtil.join(skill.getTrueTypeList(true), ". ");
if (StringUtils.isNotBlank(typeString))
{
infoText.appendI18nElement("in_igInfoLabelTextType", //$NON-NLS-1$
typeString);
infoText.appendLineBreak();
}
appendFacts(infoText, skill);
String aString = SkillInfoUtilities.getKeyStatFromStats(pc, skill);
if (!aString.isEmpty())
{
infoText.appendI18nElement("in_iskKEY_STAT", aString); //$NON-NLS-1$
}
infoText.appendLineBreak();
infoText.appendI18nElement("in_iskUntrained", //$NON-NLS-1$
skill.getSafe(ObjectKey.USE_UNTRAINED) ? LanguageBundle
.getString("in_yes") : LanguageBundle.getString("in_no"));
infoText.appendLineBreak();
infoText.appendI18nElement("in_iskEXCLUSIVE", //$NON-NLS-1$
skill.getSafe(ObjectKey.EXCLUSIVE) ? LanguageBundle
.getString("in_yes") : LanguageBundle.getString("in_no"));
String bString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null, skill
.getPrerequisiteList(), false);
if (!bString.isEmpty())
{
infoText.appendI18nFormattedElement("in_InfoRequirements", //$NON-NLS-1$
bString);
}
//Description
String desc = pc.getDescription(skill);
if (!desc.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(skill, desc, false));
}
bString = skill.getSource();
if (!bString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_iskSource", bString); //$NON-NLS-1$
}
if (PCGenSettings.OPTIONS_CONTEXT.getBoolean(
PCGenSettings.OPTION_SHOW_SKILL_MOD_BREAKDOWN, false))
{
bString = SkillCostDisplay.getModifierExplanation(skill, pc, false);
if (!bString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_iskHtml_PcMod", //$NON-NLS-1$
bString);
}
}
if (PCGenSettings.OPTIONS_CONTEXT.getBoolean(
PCGenSettings.OPTION_SHOW_SKILL_RANK_BREAKDOWN, false))
{
bString = SkillCostDisplay.getRanksExplanation(pc, skill);
if (bString.isEmpty())
{
bString = LanguageBundle.getString("in_none"); //$NON-NLS-1$
}
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_iskHtml_Ranks", //$NON-NLS-1$
bString);
}
return infoText.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.AbilityFacade)
*/
@Override
public String getHTMLInfo(AbilityFacade abilityFacade)
{
if (!(abilityFacade instanceof Ability))
{
return EMPTY_STRING;
}
Ability ability = (Ability) abilityFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(OutputNameFormatting.piString(ability, false));
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("Ability.Info.Type", //$NON-NLS-1$
StringUtil.join(ability.getTrueTypeList(true), ". ")); //$NON-NLS-1$
BigDecimal costStr = ability.getSafe(ObjectKey.SELECTION_COST);
if (!costStr.equals(BigDecimal.ONE)) //$NON-NLS-1$
{
infoText.appendI18nFormattedElement("Ability.Info.Cost", //$NON-NLS-1$
COST_FMT.format(costStr));
}
if (ability.getSafe(ObjectKey.MULTIPLE_ALLOWED))
{
infoText.appendSpacer();
infoText.append(LanguageBundle.getString("Ability.Info.Multiple")); //$NON-NLS-1$
}
if (ability.getSafe(ObjectKey.STACKS))
{
infoText.appendSpacer();
infoText.append(LanguageBundle.getString("Ability.Info.Stacks")); //$NON-NLS-1$
}
appendFacts(infoText, ability);
final String cString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
ability.getPrerequisiteList(), false);
if (!cString.isEmpty())
{
infoText.appendI18nFormattedElement("in_InfoRequirements", //$NON-NLS-1$
cString);
}
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
getDescription(abilityFacade));
List<CNAbility> wrappedAbility = getWrappedAbility(ability);
if (ability.getSafeSizeOfMapFor(MapKey.ASPECT) > 0)
{
Set<AspectName> aspectKeys = ability.getKeysFor(MapKey.ASPECT);
StringBuilder buff = new StringBuilder(100);
for (AspectName key : aspectKeys)
{
if (buff.length() > 0)
{
buff.append(", ");
}
//Assert here that the actual text displayed is not critical
buff.append(Aspect.printAspect(pc, key, wrappedAbility));
}
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("Ability.Info.Aspects", //$NON-NLS-1$
buff.toString());
}
final String bene = BenefitFormatting.getBenefits(pc, wrappedAbility);
if (bene != null && !bene.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("Ability.Info.Benefit", //$NON-NLS-1$
BenefitFormatting.getBenefits(pc, wrappedAbility));
}
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoSource", //$NON-NLS-1$
ability.getSource());
return infoText.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.DeityFacade)
*/
@Override
public String getHTMLInfo(DeityFacade deityFacade)
{
if (!(deityFacade instanceof Deity))
{
return EMPTY_STRING;
}
Deity aDeity = (Deity) deityFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
if (aDeity != null)
{
infoText.appendTitleElement(OutputNameFormatting.piString(aDeity, false));
infoText.appendLineBreak();
infoText
.appendI18nFormattedElement(
"in_InfoDescription", DescriptionFormatting.piWrapDesc(aDeity, pc.getDescription(aDeity), false)); //$NON-NLS-1$
appendFacts(infoText, aDeity);
String aString = getPantheons(aDeity);
if (aString != null)
{
infoText.appendSpacer();
infoText.appendI18nElement(
"in_pantheon", aString); //$NON-NLS-1$
}
infoText.appendSpacer();
infoText.appendI18nElement(
"in_domains", getDomains(aDeity)); //$NON-NLS-1$
List<CDOMReference<WeaponProf>> dwp = aDeity.getListFor(
ListKey.DEITYWEAPON);
if (dwp != null)
{
infoText.appendSpacer();
infoText.appendI18nFormattedElement(
"in_deityFavWeap", //$NON-NLS-1$
ReferenceUtilities.joinLstFormat(dwp, "|"));
}
aString = PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
aDeity.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nFormattedElement("in_InfoRequirements", //$NON-NLS-1$
aString);
}
aString = aDeity.getSource();
if (!aString.isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nFormattedElement("in_InfoSource", //$NON-NLS-1$
aString);
}
}
return infoText.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.DomainFacade)
*/
@Override
public String getHTMLInfo(DomainFacade domainFacade)
{
if (!(domainFacade instanceof DomainFacadeImpl))
{
return EMPTY_STRING;
}
DomainFacadeImpl domainFI = (DomainFacadeImpl) domainFacade;
Domain aDomain = domainFI.getRawObject();
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
if (aDomain != null)
{
infoText.appendTitleElement(OutputNameFormatting.piString(aDomain, false));
appendFacts(infoText, aDomain);
String aString = pc.getDescription(aDomain);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_domainGrant", //$NON-NLS-1$
aString);
}
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
aDomain.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendI18nFormattedElement("in_InfoRequirements", //$NON-NLS-1$
aString);
}
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, aDomain,
domainFI.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement(
"in_domainRequirements", //$NON-NLS-1$
aString);
}
aString =
SourceFormat.getFormattedString(aDomain, Globals
.getSourceDisplay(), true);
if (!aString.isEmpty())
{
infoText.appendI18nFormattedElement("in_InfoSource", //$NON-NLS-1$
aString);
}
}
return infoText.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.EquipmentFacade)
*/
@Override
public String getHTMLInfo(EquipmentFacade equipFacade)
{
if (equipFacade == null || !(equipFacade instanceof Equipment))
{
return EMPTY_STRING;
}
Equipment equip = (Equipment) equipFacade;
final HtmlInfoBuilder b = getEquipmentHtmlInfo(equip);
String bString = equip.getSource();
if (!bString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextSource", bString); //$NON-NLS-1$
}
b.appendLineBreak();
return b.toString();
}
private HtmlInfoBuilder getEquipmentHtmlInfo(Equipment equip)
{
final StringBuilder title = new StringBuilder(50);
title.append(OutputNameFormatting.piString(equip, false));
if (!equip.longName().equals(equip.getName()))
{
title.append("(").append(equip.longName()).append(")");
}
final HtmlInfoBuilder b = new HtmlInfoBuilder(null, false);
File icon = equip.getIcon();
if (icon != null)
{
b.appendIconElement(icon.toURI().toString());
}
b.appendTitleElement(title.toString());
b.appendLineBreak();
String baseName = equip.getBaseItemName();
if (StringUtils.isNotEmpty(baseName) && !baseName.equals(equip.getName()))
{
b.appendI18nElement("in_igInfoLabelTextBaseItem", //$NON-NLS-1$
baseName);
b.appendLineBreak();
}
b.appendI18nElement("in_igInfoLabelTextType", //$NON-NLS-1$
StringUtil.join(equip.getTrueTypeList(true), ". "));
appendFacts(b, equip);
//
// Should only be meaningful for weapons, but if included on some other piece of
// equipment, show it anyway
//
if (equip.isWeapon() || equip.get(ObjectKey.WIELD) != null)
{
b.appendLineBreak();
final WieldCategory wCat = equip.getEffectiveWieldCategory(pc);
if (wCat != null)
{
b.appendI18nElement("in_igInfoLabelTextWield", //$NON-NLS-1$
wCat.getDisplayName());
}
}
//
// Only meaningful for weapons, armor and shields
//
if (equip.isWeapon() || equip.isArmor() || equip.isShield())
{
b.appendLineBreak();
final String value =
(pc.isProficientWith(equip) && equip.meetsPreReqs(pc))
? LanguageBundle.getString("in_igInfoLabelTextYes") //$NON-NLS-1$
: (SettingsHandler.getPrereqFailColorAsHtmlStart()
+ LanguageBundle.getString("in_igInfoLabelTextNo") + //$NON-NLS-1$
SettingsHandler.getPrereqFailColorAsHtmlEnd());
b.appendI18nElement("in_igInfoLabelTextProficient", value); //$NON-NLS-1$
}
final String cString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null, equip
.getPrerequisiteList(), false);
if (!cString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextReq", cString); //$NON-NLS-1$
}
BigDecimal cost = equip.getCost(pc);
if (cost != BigDecimal.ZERO)
{
b.appendLineBreak();
b.appendI18nElement("in_igEqModelColCost", COST_FMT.format(cost.doubleValue())); //$NON-NLS-1$
b.append(" ");
b.append(SettingsHandler.getGame().getCurrencyDisplay());
}
String bString =
Globals.getGameModeUnitSet().displayWeightInUnitSet(
equip.getWeight(pc).doubleValue());
if (!bString.isEmpty())
{
b.appendLineBreak();
bString += Globals.getGameModeUnitSet().getWeightUnit();
b.appendI18nElement("in_igInfoLabelTextWeight", bString); //$NON-NLS-1$
}
Integer a = EqToken.getMaxDexTokenInt(pc, equip);
if (a.intValue() != Constants.MAX_MAXDEX)
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextMaxDex", a.toString()); //$NON-NLS-1$
}
a = EqToken.getAcCheckTokenInt(pc, equip);
if (equip.isArmor() || equip.isShield() || (a.intValue() != 0))
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextAcCheck", a.toString()); //$NON-NLS-1$
}
if (!SettingsHandler.getGame().getACText().isEmpty())
{
a = equip.getACMod(pc);
if (equip.isArmor() || equip.isShield() || (a.intValue() != 0))
{
b.appendSpacer();
b.appendElement(LanguageBundle.getFormattedString(
"in_igInfoLabelTextAcBonus", //$NON-NLS-1$
SettingsHandler.getGame().getACText()), a.toString());
}
}
if (SettingsHandler.getGame().getTabShown(Tab.SPELLS))
{
a = EqToken.getSpellFailureTokenInt(pc, equip);
if (equip.isArmor() || equip.isShield() || (a.intValue() != 0))
{
b.appendSpacer();
b.appendI18nElement(
"in_igInfoLabelTextArcaneFailure", a.toString()); //$NON-NLS-1$
}
}
bString = SettingsHandler.getGame().getDamageResistanceText();
if (!bString.isEmpty())
{
a = EqToken.getEdrTokenInt(pc, equip);
if (equip.isArmor() || equip.isShield() || (a.intValue() != 0))
{
b.appendSpacer();
b.appendElement(bString, a.toString());
}
}
bString = equip.moveString();
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextMove", bString); //$NON-NLS-1$
}
bString = equip.getSize();
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextSize", bString); //$NON-NLS-1$
}
bString = equip.getDamage(pc);
if (!bString.isEmpty())
{
if (equip.isDouble())
{
bString += "/" + equip.getAltDamage(pc); //$NON-NLS-1$
}
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextDamage", bString); //$NON-NLS-1$
}
String critRangeVar =
ControlUtilities.getControlToken(Globals.getContext(),
CControl.CRITRANGE);
if (critRangeVar == null)
{
int critrange = EqToken.getOldBonusedCritRange(pc, equip, true);
int altcritrange = EqToken.getOldBonusedCritRange(pc, equip, false);
bString = critrange == 0 ? EMPTY_STRING : Integer.toString(critrange);
if (equip.isDouble() && critrange != altcritrange)
{
bString +=
"/" //$NON-NLS-1$
+ (altcritrange == 0 ? EMPTY_STRING : Integer
.toString(altcritrange));
}
}
else
{
bString =
WeaponToken.getNewCritRangeString(pc, equip, critRangeVar);
}
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_ieInfoLabelTextCritRange", bString); //$NON-NLS-1$
}
String critMultVar =
ControlUtilities.getControlToken(Globals.getContext(),
CControl.CRITMULT);
if (critMultVar == null)
{
bString = EqToken.multAsString(equip.getCritMultiplier());
if (equip.isDouble()
&& !(equip.getCritMultiplier() == equip.getAltCritMultiplier()))
{
bString += "/" + EqToken.multAsString(equip.getAltCritMultiplier()); //$NON-NLS-1$
}
}
else
{
bString =
WeaponToken.getNewCritMultString(pc, equip, critMultVar);
}
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextCritMult", bString); //$NON-NLS-1$
}
if (equip.isWeapon())
{
bString =
Globals.getGameModeUnitSet().displayDistanceInUnitSet(
EqToken.getRange(pc, equip).intValue());
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextRange", bString + //$NON-NLS-1$
Globals.getGameModeUnitSet().getDistanceUnit());
}
}
bString = equip.getContainerCapacityString();
if (!bString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextContainer", bString); //$NON-NLS-1$
}
bString = equip.getContainerContentsString();
if (!bString.isEmpty())
{
b.appendSpacer();
b.appendI18nElement("in_igInfoLabelTextCurrentlyContains", bString); //$NON-NLS-1$
}
final int charges = equip.getRemainingCharges();
if (charges >= 0)
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextCharges", Integer.valueOf( //$NON-NLS-1$
charges).toString());
}
Map<String, String> qualityMap = equip.getMapFor(MapKey.QUALITY);
if (qualityMap != null && !qualityMap.isEmpty())
{
Set<String> qualities = new TreeSet<>();
for (Map.Entry<String, String> me : qualityMap.entrySet())
{
qualities.add(new StringBuilder(50).append(me.getKey()).append(
": ").append(me.getValue()).toString());
}
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextQualities", StringUtil.join( //$NON-NLS-1$
qualities, ", ")); //$NON-NLS-2$
}
//Description
String desc = pc.getDescription(equip);
if (!desc.isEmpty())
{
b.appendLineBreak();
b.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(equip, desc, false));
}
String IDS = equip.getInterestingDisplayString(pc);
if (!IDS.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextProp", IDS); //$NON-NLS-1$
}
String note = equip.getNote();
if (!note.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextNote", note); //$NON-NLS-1$
}
return b;
}
@Override
public String getHTMLInfo(EquipModFacade equipModFacade, EquipmentFacade equipFacade)
{
if (equipModFacade == null
|| !(equipModFacade instanceof EquipmentModifier)
|| equipFacade == null || !(equipFacade instanceof Equipment))
{
return EMPTY_STRING;
}
EquipmentModifier equipMod = (EquipmentModifier) equipModFacade;
Equipment equip = (Equipment) equipFacade;
final StringBuilder title = new StringBuilder(50);
title.append(OutputNameFormatting.piString(equipMod, false));
final HtmlInfoBuilder b = new HtmlInfoBuilder(null, false);
b.appendTitleElement(title.toString());
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextType", //$NON-NLS-1$
StringUtil.join(equipMod.getTrueTypeList(true), ". "));
// Various cost types
int iPlus = equipMod.getSafe(IntegerKey.PLUS);
if (iPlus != 0)
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextPlus", String.valueOf(iPlus));
}
Formula baseCost = equipMod.getSafe(FormulaKey.BASECOST);
if (!"0".equals(baseCost.toString()))
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextPrecost", String.valueOf(baseCost));
}
Formula cost = equipMod.getSafe(FormulaKey.COST);
if (!"0".equals(cost.toString()))
{
b.appendLineBreak();
b.appendI18nElement("in_igEqModelColCost", String.valueOf(cost));
}
//Description
String desc = pc.getDescription(equipMod);
if (!desc.isEmpty())
{
b.appendLineBreak();
b.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(equipMod, desc, false));
}
// Special properties
StringBuilder sb = new StringBuilder(100);
boolean first = true;
for (SpecialProperty sp : equipMod.getSafeListFor(ListKey.SPECIAL_PROPERTIES))
{
if (!first)
{
sb.append(", ");
}
first = false;
sb.append(sp.getDisplayName());
}
if (sb.length() > 0)
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextSprop", sb.toString());
}
final String cString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, equip, equipMod
.getPrerequisiteList(), false);
if (!cString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextReq", cString); //$NON-NLS-1$
}
String bString = equipMod.getSource();
if (!bString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_igInfoLabelTextSource", bString); //$NON-NLS-1$
}
b.appendLineBreak();
return b.toString();
}
/**
* @param equipMod
* @return Object
*/
protected String getCostValue(EquipmentModifier equipMod)
{
int iPlus = equipMod.getSafe(IntegerKey.PLUS);
StringBuilder eCost = new StringBuilder(20);
if (iPlus != 0)
{
eCost.append("Plus:").append(iPlus);
}
Formula baseCost = equipMod.getSafe(FormulaKey.BASECOST);
if (!"0".equals(baseCost.toString()))
{
if (eCost.length() != 0)
{
eCost.append(", ");
}
eCost.append("Precost:").append(baseCost);
}
Formula cost = equipMod.getSafe(FormulaKey.BASECOST);
if (!"0".equals(cost.toString()))
{
if (eCost.length() != 0)
{
eCost.append(", ");
}
eCost.append("Cost:").append(cost);
}
String sRet = eCost.toString();
return sRet;
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getHTMLInfo(pcgen.core.facade.TemplateFacade)
*/
@Override
public String getHTMLInfo(TemplateFacade templateFacade)
{
if (templateFacade == null)
{
return EMPTY_STRING;
}
PCTemplate template = (PCTemplate) templateFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(OutputNameFormatting.piString(template,
false));
appendFacts(infoText, template);
RaceType rt = template.get(ObjectKey.RACETYPE);
if (rt != null)
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_irInfoRaceType", rt.toString()); //$NON-NLS-1$
}
if (!template.getType().isEmpty())
{
infoText.appendSpacer();
infoText.appendI18nElement("in_irInfoType", template.getType()); //$NON-NLS-1$
}
String aString = pc.getDescription(template);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
aString);
}
aString = TemplateModifier.modifierString(template, pc);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_modifier", aString); //$NON-NLS-1$
}
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
template.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_requirements", aString); //$NON-NLS-1$
}
aString = template.getSource();
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_sourceLabel", aString); //$NON-NLS-1$
}
return infoText.toString();
}
@Override
public String getHTMLInfo(KitFacade kitFacade)
{
if (kitFacade == null)
{
return EMPTY_STRING;
}
Kit kit = (Kit) kitFacade;
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(OutputNameFormatting.piString(kit, false));
appendFacts(infoText, kit);
String aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
kit.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_requirements", aString); //$NON-NLS-1$
}
List<BaseKit> sortedObjects = new ArrayList<>();
sortedObjects.addAll(kit.getSafeListFor(ListKey.KIT_TASKS));
sortedObjects.sort(new ObjectTypeComparator());
String lastObjectName = EMPTY_STRING;
for (BaseKit bk : sortedObjects)
{
String objName = bk.getObjectName();
if (!objName.equals(lastObjectName))
{
if (!EMPTY_STRING.equals(lastObjectName))
{
infoText.append("; ");
}
else
{
infoText.appendLineBreak();
}
infoText.append(" <b>" + objName + "</b>: ");
lastObjectName = objName;
}
else
{
infoText.append(", ");
}
infoText.append(bk.toString());
}
BigDecimal totalCost = kit.getTotalCost(pc);
if (totalCost != null)
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_kitInfo_TotalCost", //$NON-NLS-1$
COST_FMT.format(totalCost),
SettingsHandler.getGame().getCurrencyDisplay());
}
String desc = pc.getDescription(kit);
if (!desc.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nFormattedElement("in_InfoDescription", //$NON-NLS-1$
DescriptionFormatting.piWrapDesc(kit, desc, false));
}
aString = kit.getSource();
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_sourceLabel", aString); //$NON-NLS-1$
}
//TODO ListKey.KIT_TASKS
return infoText.toString();
}
@Override
public String getHTMLInfo(TempBonusFacade tempBonusFacade)
{
if (tempBonusFacade == null)
{
return EMPTY_STRING;
}
if (!(tempBonusFacade instanceof TempBonusFacadeImpl))
{
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(tempBonusFacade.toString());
return infoText.toString();
}
TempBonusFacadeImpl tempBonus = (TempBonusFacadeImpl) tempBonusFacade;
CDOMObject originObj = tempBonus.getOriginObj();
final HtmlInfoBuilder infoText;
if (originObj instanceof Equipment)
{
infoText = getEquipmentHtmlInfo((Equipment) originObj);
}
else
{
infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(OutputNameFormatting.piString(originObj, false));
infoText.append(" (").append(tempBonus.getOriginType()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (tempBonus.getTarget() != null)
{
String targetName = charDisplay.getName();
if (tempBonus.getTarget() instanceof CDOMObject)
{
targetName = ((CDOMObject) tempBonus.getTarget()).getKeyName();
}
infoText.appendLineBreak();
infoText.appendI18nElement("in_itmInfoLabelTextTarget", targetName); //$NON-NLS-1$
StringBuilder bonusValues = new StringBuilder(100);
Map<BonusObj, TempBonusInfo> bonusMap = pc.getTempBonusMap(originObj.getKeyName(), targetName);
boolean first = true;
List<BonusObj> bonusList = new ArrayList<>(bonusMap.keySet());
bonusList.sort(new BonusComparator());
for (BonusObj bonusObj : bonusList)
{
if (!first)
{
bonusValues.append(", "); //$NON-NLS-1$
}
first = false;
String adj = ADJ_FMT.format(bonusObj.resolve(pc, "")); //$NON-NLS-1$
bonusValues.append(adj + " " + bonusObj.getDescription()); //$NON-NLS-1$
}
if (bonusValues.length() > 0)
{
infoText.appendLineBreak();
infoText.appendI18nElement(
"in_itmInfoLabelTextEffect", //$NON-NLS-1$
bonusValues.toString());
}
}
if (originObj instanceof Spell)
{
Spell aSpell = (Spell) originObj;
infoText.appendLineBreak();
infoText.appendI18nElement("in_spellDuration", //$NON-NLS-1$
aSpell.getListAsString(ListKey.DURATION));
infoText.appendSpacer();
infoText.appendI18nElement("in_spellRange", //$NON-NLS-1$
aSpell.getListAsString(ListKey.RANGE));
infoText.appendSpacer();
infoText.appendI18nElement("in_spellTarget", //$NON-NLS-1$
aSpell.getSafe(StringKey.TARGET_AREA));
}
String aString = originObj.getSafe(StringKey.TEMP_DESCRIPTION);
if (StringUtils.isEmpty(aString) && originObj instanceof Spell)
{
Spell sp = (Spell) originObj;
aString = DescriptionFormatting.piWrapDesc(sp, pc.getDescription(sp),
false);
}
else if (StringUtils.isEmpty(aString) && originObj instanceof Ability)
{
Ability ab = (Ability) originObj;
List<CNAbility> wrappedAbility =
Collections.singletonList(CNAbilityFactory.getCNAbility(ab
.getCDOMCategory(), Nature.NORMAL, ab));
aString = DescriptionFormatting.piWrapDesc(ab,
pc.getDescription(wrappedAbility), false);
}
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_itmInfoLabelTextDesc", aString); //$NON-NLS-1$
}
aString =
PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
originObj.getPrerequisiteList(), false);
if (!aString.isEmpty())
{
infoText.appendLineBreak();
infoText.appendI18nElement("in_requirements", aString); //$NON-NLS-1$
}
infoText.appendLineBreak();
infoText.appendI18nElement(
"in_itmInfoLabelTextSource", //$NON-NLS-1$
SourceFormat.getFormattedString(originObj,
Globals.getSourceDisplay(), true));
return infoText.toString();
}
@Override
public String getHTMLInfo(InfoFacade facade)
{
if (facade == null)
{
return EMPTY_STRING;
}
// Use a more detailed info if we can
if (facade instanceof AbilityFacade)
{
return getHTMLInfo((AbilityFacade) facade);
}
if (facade instanceof ClassFacade)
{
return getHTMLInfo((ClassFacade) facade, null);
}
if (facade instanceof DeityFacade)
{
return getHTMLInfo((DeityFacade) facade);
}
if (facade instanceof DomainFacade)
{
return getHTMLInfo((DomainFacade) facade);
}
if (facade instanceof EquipmentFacade)
{
return getHTMLInfo((EquipmentFacade) facade);
}
if (facade instanceof KitFacade)
{
return getHTMLInfo((KitFacade) facade);
}
if (facade instanceof RaceFacade)
{
return getHTMLInfo((RaceFacade) facade);
}
if (facade instanceof SkillFacade)
{
return getHTMLInfo((SkillFacade) facade);
}
if (facade instanceof SpellFacade)
{
return getHTMLInfo((SpellFacade) facade);
}
if (facade instanceof TempBonusFacade)
{
return getHTMLInfo((TempBonusFacade) facade);
}
if (facade instanceof TemplateFacade)
{
return getHTMLInfo((TemplateFacade) facade);
}
final HtmlInfoBuilder infoText = new HtmlInfoBuilder();
infoText.appendTitleElement(facade.toString());
infoText.appendLineBreak();
if (!facade.getType().isEmpty())
{
infoText.appendI18nElement("in_irInfoType", facade.getType()); //$NON-NLS-1$
infoText.appendLineBreak();
}
infoText.appendI18nElement(
"in_itmInfoLabelTextSource", //$NON-NLS-1$
facade.getSource());
return infoText.toString();
}
private static class ObjectTypeComparator implements Comparator<BaseKit>
{
@Override
public int compare(BaseKit bk1, BaseKit bk2)
{
String name1 = bk1.getObjectName();
String name2 = bk2.getObjectName();
return name1.compareTo(name2);
}
}
private static class BonusComparator implements Comparator<BonusObj>
{
@Override
public int compare(BonusObj bo1, BonusObj bo2)
{
String type1 = bo1.getTypeOfBonus();
String type2 = bo2.getTypeOfBonus();
if (!type1.equals(type2))
{
return type1.compareTo(type2);
}
return bo1.getBonusInfo().compareTo(bo2.getBonusInfo());
}
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getLevelAdjustment(pcgen.core.facade.RaceFacade)
*/
@Override
public String getLevelAdjustment(RaceFacade raceFacade)
{
if (!(raceFacade instanceof Race))
{
return EMPTY_STRING;
}
Race race = (Race) raceFacade;
return ADJ_FMT.format(race.getSafe(FormulaKey.LEVEL_ADJUSTMENT)
.resolve(pc, EMPTY_STRING));
}
@Override
public int getNumMonsterClassLevels(RaceFacade raceFacade)
{
if (!(raceFacade instanceof Race))
{
return 0;
}
Race race = (Race) raceFacade;
LevelCommandFactory levelCommandFactory =
race.get(ObjectKey.MONSTER_CLASS);
if (levelCommandFactory == null)
{
return 0;
}
return levelCommandFactory.getLevelCount().resolve(pc, EMPTY_STRING)
.intValue();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getPreReqHTML(pcgen.core.facade.RaceFacade)
*/
@Override
public String getPreReqHTML(RaceFacade race)
{
if (!(race instanceof Race))
{
return EMPTY_STRING;
}
return PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
((Race) race).getPrerequisiteList(), true);
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getStatAdjustments(pcgen.core.facade.RaceFacade)
*/
@Override
public String getStatAdjustments(RaceFacade raceFacade)
{
if (!(raceFacade instanceof Race))
{
return EMPTY_STRING;
}
Race race = (Race) raceFacade;
final StringBuilder retString = new StringBuilder(100);
for (PCStat stat : charDisplay.getStatSet())
{
if (charDisplay.isNonAbility(stat))
{
if (retString.length() > 0)
{
retString.append(' ');
}
retString.append(stat.getKeyName() + ":Nonability");
}
else
{
if (BonusCalc.getStatMod(race, stat, pc) != 0)
{
if (retString.length() > 0)
{
retString.append(' ');
}
retString.append(stat.getKeyName() + ":"
+ BonusCalc.getStatMod(race, stat, pc));
}
}
}
return retString.toString();
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getVision(pcgen.core.facade.RaceFacade)
*/
@Override
public String getVision(RaceFacade race)
{
if (!(race instanceof Race))
{
return EMPTY_STRING;
}
return VisionDisplay.getVision(pc, (Race) race);
}
@Override
public float getCost(EquipmentFacade equipment)
{
if (equipment instanceof Equipment)
{
return ((Equipment) equipment).getCost(pc).floatValue();
}
return 0;
}
@Override
public float getWeight(EquipmentFacade equipment)
{
if (equipment instanceof Equipment)
{
Float weight = ((Equipment) equipment).getWeight(pc);
return (float) Globals.getGameModeUnitSet().convertWeightToUnitSet(weight);
}
return 0;
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getLevelAdjustment(pcgen.core.facade.TemplateFacade)
*/
@Override
public String getLevelAdjustment(TemplateFacade templateFacade)
{
if (!(templateFacade instanceof PCTemplate))
{
return EMPTY_STRING;
}
PCTemplate template = (PCTemplate) templateFacade;
return ADJ_FMT.format(template.getSafe(FormulaKey.LEVEL_ADJUSTMENT)
.resolve(pc, EMPTY_STRING));
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getModifier(pcgen.core.facade.TemplateFacade)
*/
@Override
public String getModifier(TemplateFacade templateFacade)
{
if (!(templateFacade instanceof PCTemplate))
{
return EMPTY_STRING;
}
PCTemplate template = (PCTemplate) templateFacade;
return TemplateModifier.modifierString(template, pc);
}
/* (non-Javadoc)
* @see pcgen.core.facade.InfoFactory#getPreReqHTML(pcgen.core.facade.TemplateFacade)
*/
@Override
public String getPreReqHTML(TemplateFacade template)
{
if (!(template instanceof PCTemplate))
{
return EMPTY_STRING;
}
return PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
((PCTemplate) template).getPrerequisiteList(), true);
}
@Override
public String getHTMLInfo(SpellFacade spell)
{
if (spell == null || !(spell instanceof SpellFacadeImplem))
{
return EMPTY_STRING;
}
SpellFacadeImplem sfi = (SpellFacadeImplem) spell;
CharacterSpell cs = sfi.getCharSpell();
SpellInfo si = sfi.getSpellInfo();
Spell aSpell = cs.getSpell();
if (aSpell == null)
{
return EMPTY_STRING;
}
final HtmlInfoBuilder b =
new HtmlInfoBuilder(OutputNameFormatting.piString(aSpell, false));
if (si != null)
{
final String addString = si.toString(); // would add [featList]
if (!addString.isEmpty())
{
b.append(" ").append(addString); //$NON-NLS-1$
}
b.appendLineBreak();
b.appendI18nElement("InfoSpells.level.title", Integer.toString(si.getOriginalLevel())); //$NON-NLS-1$
}
b.appendLineBreak();
String classlevels = aSpell.getListAsString(ListKey.SPELL_CLASSLEVEL);
if (StringUtils.isNotEmpty(classlevels))
{
b.appendI18nElement("in_clClass", classlevels);
b.appendLineBreak();
}
String domainlevels = aSpell.getListAsString(ListKey.SPELL_DOMAINLEVEL);
if (StringUtils.isNotEmpty(domainlevels))
{
b.appendI18nElement("in_domains", domainlevels);
b.appendLineBreak();
}
b.appendI18nElement("in_spellSchool",
aSpell.getListAsString(ListKey.SPELL_SCHOOL));
String subSchool = aSpell.getListAsString(ListKey.SPELL_SUBSCHOOL);
if (StringUtils.isNotEmpty(subSchool))
{
b.append(" (").append(subSchool).append(")");
}
String spellDescriptor =
aSpell.getListAsString(ListKey.SPELL_DESCRIPTOR);
if (StringUtils.isNotEmpty(spellDescriptor))
{
b.append(" [").append(spellDescriptor).append("]");
}
b.appendLineBreak();
appendFacts(b, aSpell);
b.appendLineBreak();
b.appendI18nElement("in_spellComponents",
aSpell.getListAsString(ListKey.COMPONENTS));
b.appendLineBreak();
b.appendI18nElement("in_spellCastTime",
aSpell.getListAsString(ListKey.CASTTIME));
b.appendLineBreak();
b.appendI18nElement("in_spellDuration",
pc.parseSpellString(cs, aSpell.getListAsString(ListKey.DURATION)));
b.appendLineBreak();
b.appendI18nElement("in_spellRange", pc.getSpellRange(cs, si));
b.appendSpacer();
b.appendI18nElement("in_spellTarget",
pc.parseSpellString(cs, aSpell.getSafe(StringKey.TARGET_AREA)));
b.appendLineBreak();
b.appendI18nElement("in_spellSavingThrow",
aSpell.getListAsString(ListKey.SAVE_INFO));
b.appendSpacer();
b.appendI18nElement("in_spellSpellResist",
aSpell.getListAsString(ListKey.SPELL_RESISTANCE));
b.appendLineBreak();
b.appendLineBreak();
b.appendI18nElement("in_descrip", pc.parseSpellString(cs, //$NON-NLS-1$
pc.getDescription(aSpell)));
final String cString = PrerequisiteUtilities.preReqHTMLStringsForList(pc, null,
aSpell.getPrerequisiteList(), false);
if (!cString.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_requirements", cString); //$NON-NLS-1$
}
b.appendLineBreak();
String spellSource = SourceFormat.getFormattedString(aSpell,
Globals.getSourceDisplay(), true);
if (!spellSource.isEmpty())
{
b.appendLineBreak();
b.appendI18nElement("in_source", spellSource); //$NON-NLS-1$
}
return b.toString();
}
@Override
public String getSpellBookInfo(String name)
{
SpellBook book = charDisplay.getSpellBookByName(name);
if (book == null)
{
return EMPTY_STRING;
}
switch (book.getType())
{
case SpellBook.TYPE_PREPARED_LIST:
return produceSpellListInfo(book);
case SpellBook.TYPE_SPELL_BOOK:
return produceSpellBookInfo(book);
default:
return EMPTY_STRING;
}
}
/**
* Produce the HTML info label for a prepared spell list.
* @param book The spell list being output.
* @return The HTML info for the list.
*/
private String produceSpellListInfo(SpellBook spelllist)
{
final HtmlInfoBuilder b =
new HtmlInfoBuilder(spelllist.getName());
b.append(" ("); //$NON-NLS-1$
b.append(spelllist.getTypeName());
b.append(")"); //$NON-NLS-1$
b.appendLineBreak();
if (spelllist.getDescription() != null)
{
b.appendI18nElement("in_descrip", spelllist.getDescription()); //$NON-NLS-1$
b.appendLineBreak();
}
// Look at each spell on each spellcasting class
for (PCClass pcClass : charDisplay.getClassSet())
{
Map<Integer, Integer> spellCountMap = new TreeMap<>();
int highestSpellLevel = -1;
Collection<? extends CharacterSpell> sp = charDisplay.getCharacterSpells(pcClass);
List<CharacterSpell> classSpells = new ArrayList<>(sp);
// Add in the spells granted by objects
pc.addBonusKnownSpellsToList(pcClass, classSpells);
for (CharacterSpell charSpell : classSpells)
{
for (SpellInfo spellInfo : charSpell.getInfoList())
{
if (!spelllist.getName().equals(spellInfo.getBook()))
{
continue;
}
int level = spellInfo.getActualLevel();
int count = spellCountMap.containsKey(level) ? spellCountMap.get(level) : 0;
count += spellInfo.getTimes();
spellCountMap.put(level, count);
if (level > highestSpellLevel)
{
highestSpellLevel = level;
}
}
}
if (!spellCountMap.isEmpty())
{
b.append("<table border=1><tr><td><font size=-1><b>"); //$NON-NLS-1$
b.append(OutputNameFormatting.piString(pcClass, false));
b.append("</b></font></td>"); //$NON-NLS-1$
for (int i = 0; i <= highestSpellLevel; ++i)
{
b.append("<td><font size=-2><b><center> "); //$NON-NLS-1$
b.append(String.valueOf(i));
b.append(" </b></center></font></td>"); //$NON-NLS-1$
}
b.append("</tr>"); //$NON-NLS-1$
b.append("<tr><td><font size=-1><b>Prepared</b></font></td>"); //$NON-NLS-1$
for (int i = 0; i <= highestSpellLevel; ++i)
{
b.append("<td><font size=-1><center>"); //$NON-NLS-1$
b.append(String.valueOf(spellCountMap.get(i) == null ? 0
: spellCountMap.get(i)));
b.append("</center></font></td>"); //$NON-NLS-1$
}
b.append("</tr></table>"); //$NON-NLS-1$
b.appendLineBreak();
}
}
return b.toString();
}
/**
* Produce the HTML info label for a spell book.
* @param book The spell book being output.
* @return The HTML info for the book.
*/
private String produceSpellBookInfo(SpellBook book)
{
final HtmlInfoBuilder b =
new HtmlInfoBuilder(book.getName());
b.append(" ("); //$NON-NLS-1$
b.append(book.getTypeName());
if (book.getName().equals(charDisplay.getSpellBookNameToAutoAddKnown()))
{
b.append(TWO_SPACES).append(BOLD);
b.append(
LanguageBundle.getString("InfoSpellsSubTab.DefaultKnownBook")) //$NON-NLS-1$
.append(END_BOLD);
}
b.append(")"); //$NON-NLS-1$
b.appendLineBreak();
b.append(LanguageBundle.getFormattedString(
"InfoSpells.html.spellbook.details", //$NON-NLS-1$
new Object[]{
book.getNumPages(),
book.getNumPagesUsed(),
book.getPageFormula(),
book.getNumSpells()}));
if (book.getDescription() != null)
{
b.appendLineBreak();
b.appendI18nElement("in_descrip", book.getDescription()); //$NON-NLS-1$
}
return b.toString();
}
@Override
public String getDescription(AbilityFacade ability)
{
if (ability == null || !(ability instanceof Ability))
{
return EMPTY_STRING;
}
try
{
Ability a = (Ability) ability;
List<CNAbility> wrappedAbility = getWrappedAbility(a);
return DescriptionFormatting.piWrapDesc(a, pc.getDescription(wrappedAbility), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + ability, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(RaceFacade raceFacade)
{
if (raceFacade == null || !(raceFacade instanceof Race))
{
return EMPTY_STRING;
}
try
{
Race race = (Race) raceFacade;
return DescriptionFormatting.piWrapDesc(race, pc.getDescription(race), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + raceFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(TemplateFacade templateFacade)
{
if(templateFacade == null || !(templateFacade instanceof PCTemplate)){
return EMPTY_STRING;
}
try
{
PCTemplate template = (PCTemplate) templateFacade;
return DescriptionFormatting.piWrapDesc(template, pc.getDescription(template), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + templateFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(ClassFacade classFacade)
{
if(classFacade == null || !(classFacade instanceof PCClass)){
return EMPTY_STRING;
}
try
{
PCClass pcClass = (PCClass) classFacade;
return DescriptionFormatting.piWrapDesc(pcClass, pc.getDescription(pcClass), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + classFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(SkillFacade skillFacade)
{
if (skillFacade == null || !(skillFacade instanceof Skill))
{
return EMPTY_STRING;
}
try
{
Skill skill = (Skill) skillFacade;
return DescriptionFormatting.piWrapDesc(skill, pc.getDescription(skill), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + skillFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(EquipmentFacade equipFacade)
{
if (equipFacade == null || !(equipFacade instanceof Equipment))
{
return EMPTY_STRING;
}
try
{
Equipment equip = (Equipment) equipFacade;
return DescriptionFormatting.piWrapDesc(equip, pc.getDescription(equip), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + equipFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(KitFacade kitFacade)
{
if (kitFacade == null || !(kitFacade instanceof Kit))
{
return EMPTY_STRING;
}
try
{
Kit kit = (Kit) kitFacade;
return DescriptionFormatting.piWrapDesc(kit, pc.getDescription(kit), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + kitFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(DeityFacade deityFacade)
{
if(deityFacade == null || !(deityFacade instanceof Deity)){
return EMPTY_STRING;
}
try
{
Deity deity = (Deity) deityFacade;
return DescriptionFormatting.piWrapDesc(deity, pc.getDescription(deity), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + deityFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(DomainFacade domainFacade)
{
if(domainFacade == null || !(domainFacade instanceof DomainFacadeImpl)){
return EMPTY_STRING;
}
try
{
DomainFacadeImpl domain = (DomainFacadeImpl) domainFacade;
Domain dom = domain.getRawObject();
if(dom == null){
return EMPTY_STRING;
}
return DescriptionFormatting.piWrapDesc(dom, pc.getDescription(dom), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + domainFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(SpellFacade spellFacade)
{
if (spellFacade == null || !(spellFacade instanceof SpellFacadeImplem))
{
return EMPTY_STRING;
}
try
{
SpellFacadeImplem spell = (SpellFacadeImplem) spellFacade;
Spell aSpell = spell.getSpell();
if (aSpell == null)
{
return EMPTY_STRING;
}
return DescriptionFormatting.piWrapDesc(aSpell, pc.getDescription(aSpell), false);
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + spellFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
@Override
public String getDescription(TempBonusFacade tempBonusFacade)
{
if (tempBonusFacade == null || !(tempBonusFacade instanceof TempBonusFacadeImpl))
{
return EMPTY_STRING;
}
try
{
TempBonusFacadeImpl tempBonus = (TempBonusFacadeImpl) tempBonusFacade;
CDOMObject originObj = tempBonus.getOriginObj();
String desc = originObj.getSafe(StringKey.TEMP_DESCRIPTION);
if (StringUtils.isEmpty(desc))
{
if (originObj instanceof Spell)
{
Spell sp = (Spell) originObj;
desc = DescriptionFormatting.piWrapDesc(sp, pc.getDescription(sp),
false);
}
else if (originObj instanceof Ability)
{
Ability ab = (Ability) originObj;
List<CNAbility> wrappedAbility
= Collections.singletonList(CNAbilityFactory.getCNAbility(ab
.getCDOMCategory(), Nature.NORMAL, ab));
desc = DescriptionFormatting.piWrapDesc(ab,
pc.getDescription(wrappedAbility), false);
}
}
return desc;
}
catch (Exception e)
{
Logging.errorPrint("Failed to get description for " + tempBonusFacade, e); //$NON-NLS-1$
return EMPTY_STRING;
}
}
/**
* Retrieve a wrapped instance of the provided ability, whether the
* character has the ability or not. This will either be a list of the
* specific occurrences of the ability the character, or a list of a new
* CNAbility if the character does not possess the ability.
*
* @param a The ability to be wrapped.
* @return The list of wrapped abilities.
*/
private List<CNAbility> getWrappedAbility(Ability a)
{
/*
* TODO this is probably a problem in that it is doing a target (all
* associations for an ability, not related to the current CNAbility
* selected in the UI)
*/
List<CNAbility> wrappedAbility = pc.getMatchingCNAbilities(a);
if (wrappedAbility.isEmpty())
{
CNAbility cna = CNAbilityFactory.getCNAbility(a.getCDOMCategory(), Nature.NORMAL, a);
wrappedAbility.add(cna);
}
return wrappedAbility;
}
@Override
public String getDomains(DeityFacade deityFacade)
{
if (deityFacade == null || !(deityFacade instanceof Deity))
{
return EMPTY_STRING;
}
Deity deity = (Deity) deityFacade;
Set<String> set = new TreeSet<>();
for (CDOMReference<Domain> ref : deity.getSafeListMods(Deity.DOMAINLIST))
{
for (Domain d : ref.getContainedObjects())
{
set.add(OutputNameFormatting.piString(d, false));
}
}
final StringBuilder piString = new StringBuilder(100);
//piString.append("<html>"); //$NON-NLS-1$
piString.append(StringUtil.joinToStringBuilder(set, ", ")); //$NON-NLS-1$
//piString.append("</html>"); //$NON-NLS-1$
return piString.toString();
}
@Override
public String getPantheons(DeityFacade deityFacade)
{
if (deityFacade == null || !(deityFacade instanceof Deity))
{
return EMPTY_STRING;
}
Deity deity = (Deity) deityFacade;
Set<String> set = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
if (deity != null)
{
FactSetKey<String> fk = FactSetKey.valueOf("Pantheon");
for (Indirect<String> indirect : deity.getSafeSetFor(fk))
{
set.add(indirect.get());
}
}
final StringBuilder piString = new StringBuilder(100);
piString.append(StringUtil.joinToStringBuilder(set, ",")); //$NON-NLS-1$
return piString.toString();
}
/**
* Get a display string of the deity's favored weapons.
* @param deityFacade The deity to be output.
* @return The comma separated list of weapons.
*/
@Override
public String getFavoredWeapons(DeityFacade deityFacade)
{
if (deityFacade == null || !(deityFacade instanceof Deity))
{
return EMPTY_STRING;
}
Deity deity = (Deity) deityFacade;
List<CDOMReference<WeaponProf>> wpnList =
deity.getSafeListFor(ListKey.DEITYWEAPON);
return ReferenceUtilities.joinLstFormat(wpnList, ",");
}
@Override
public String getChoices(AbilityFacade abilityFacade)
{
if (abilityFacade == null || !(abilityFacade instanceof Ability))
{
return EMPTY_STRING;
}
final Ability ability = (Ability) abilityFacade;
final StringBuilder result = new StringBuilder(100);
Collection<CNAbility> targetAbilities = pc.getMatchingCNAbilities(ability);
if (ability.getSafe(ObjectKey.MULTIPLE_ALLOWED))
{
ChooseInformation<?> chooseInfo =
ability.get(ObjectKey.CHOOSE_INFO);
processAbilities(result, targetAbilities, chooseInfo);
}
return result.toString();
}
private <T> void processAbilities(final StringBuilder result,
Collection<CNAbility> targetAbilities, ChooseInformation<T> chooseInfo)
{
if (chooseInfo == null)
{
return;
}
List<T> choices = new ArrayList<>();
for (CNAbility ab : targetAbilities)
{
List<? extends T> sel =
(List<? extends T>) pc.getDetailedAssociations(ab);
if (sel != null)
{
choices.addAll(sel);
}
}
String choiceInfo = chooseInfo.composeDisplay(choices).toString();
if (!choiceInfo.isEmpty())
{
result.append(choiceInfo);
}
}
@Override
public String getTempBonusTarget(TempBonusFacade tempBonusFacade)
{
if (tempBonusFacade == null || !(tempBonusFacade instanceof TempBonusFacadeImpl))
{
return EMPTY_STRING;
}
TempBonusFacadeImpl tempBonus = (TempBonusFacadeImpl) tempBonusFacade;
Set<String> targetSet = new HashSet<>();
if (TempBonusHelper.hasCharacterTempBonus(tempBonus.getOriginObj()))
{
targetSet.add(LanguageBundle
.getString("in_itmBonModelTargetTypeCharacter")); //$NON-NLS-1$
}
if (TempBonusHelper.hasEquipmentTempBonus(tempBonus.getOriginObj()))
{
targetSet.addAll(TempBonusHelper.getEquipmentApplyString(tempBonus.getOriginObj()));
}
StringBuilder target = new StringBuilder(40);
for (String string : targetSet)
{
target.append(string).append(";"); //$NON-NLS-1$
}
if (target.length() > 0)
{
target.deleteCharAt(target.length()-1);
}
return target.toString();
}
@Override
public String getMovement(RaceFacade race)
{
if (!(race instanceof Race))
{
return EMPTY_STRING;
}
List<Movement> movements = ((Race) race).getListFor(ListKey.BASE_MOVEMENT);
if (movements != null && !movements.isEmpty())
{
return movements.get(0).toString();
}
return EMPTY_STRING;
}
private void appendFacts(HtmlInfoBuilder infoText, CDOMObject cdo)
{
Class<? extends CDOMObject> cl = cdo.getClass();
LoadContext context = Globals.getContext();
Collection<FactDefinition> defs =
context.getReferenceContext().getConstructedCDOMObjects(
FactDefinition.class);
for (FactDefinition<?, ?> def : defs)
{
if (def.getUsableLocation().isAssignableFrom(cl))
{
if (def.getVisibility().isVisibleTo(View.VISIBLE_DISPLAY))
{
FactKey<?> fk = def.getFactKey();
Indirect<?> fact = cdo.get(fk);
if (fact != null)
{
infoText.appendSpacer();
infoText.append("<b>");
infoText.append(fk.toString());
infoText.append(":</b> ");
infoText.append(fact.getUnconverted());
}
}
}
}
Collection<FactSetDefinition> setdefs =
context.getReferenceContext().getConstructedCDOMObjects(
FactSetDefinition.class);
for (FactSetDefinition<?, ?> def : setdefs)
{
if (def.getUsableLocation().isAssignableFrom(cl))
{
if (def.getVisibility().isVisibleTo(View.VISIBLE_DISPLAY))
{
FactSetKey<?> fk = def.getFactSetKey();
String s = getSetString(cdo, fk);
if (s != null)
{
infoText.appendSpacer();
infoText.append("<b>");
infoText.append(fk.toString());
infoText.append(":</b> ");
infoText.append(s);
}
}
}
}
}
private <T> String getSetString(CDOMObject cdo, FactSetKey<T> fk)
{
List<Indirect<T>> set = cdo.getSetFor(fk);
if (set == null)
{
return null;
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Indirect<T> indirect : set)
{
if (!first)
{
sb.append(Constants.COMMA);
}
sb.append(indirect.get());
first = false;
}
return sb.toString();
}
}