de.rpgframework.genericrpg.data.ComplexDataItem Maven / Gradle / Ivy
package de.rpgframework.genericrpg.data;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import org.prelle.simplepersist.Attribute;
import org.prelle.simplepersist.Element;
import org.prelle.simplepersist.ElementList;
import de.rpgframework.HasName;
import de.rpgframework.genericrpg.items.ItemFlag;
import de.rpgframework.genericrpg.items.PieceOfGearVariant;
import de.rpgframework.genericrpg.modification.DataItemModification;
import de.rpgframework.genericrpg.modification.Modification;
import de.rpgframework.genericrpg.modification.ModificationChoice;
import de.rpgframework.genericrpg.modification.ModificationList;
import de.rpgframework.genericrpg.modification.ModifiedObjectType;
import de.rpgframework.genericrpg.requirements.Requirement;
import de.rpgframework.genericrpg.requirements.RequirementList;
/**
* @author prelle
*
*/
public class ComplexDataItem extends DataItem implements ChoiceOrigin {
/**
* When instantiating an entity of this item, the following choices must
* be presented to the user.
*/
@ElementList(type = Choice.class, entry = "choice")
protected List choices;
@Element
protected ModificationList modifications;
@Element
protected RequirementList requires;
@Attribute(name="hasLevel")
protected boolean hasLevel;
/**
* These flags can be freely selected by a user
*/
@ElementList(entry = "flag", type = String.class, inline = false)
protected List userSelectableFlags;
//-------------------------------------------------------------------
/**
*/
public ComplexDataItem() {
choices = new ArrayList<>();
modifications = new ModificationList();
requires = new RequirementList();
}
//-------------------------------------------------------------------
public List getChoices() {
return new ArrayList(choices);
}
//-------------------------------------------------------------------
public void addChoice(Choice choice) {
if (!choices.contains(choice))
choices.add(choice);
}
//-------------------------------------------------------------------
/**
* @see de.rpgframework.genericrpg.data.ChoiceOrigin#getChoice(java.util.UUID)
*/
@Override
public Choice getChoice(UUID uuid) {
if (choices!=null) {
for (Choice choice : choices) {
if (choice.uuid==null || choice.uuid.equals(uuid))
return choice;
}
}
return null;
}
//-------------------------------------------------------------------
public Choice getChoice(String ref) {
if (choices!=null) {
for (Choice choice : choices) {
if (choice.ref!=null && choice.ref.equals(ref))
return choice;
}
}
return null;
}
//-------------------------------------------------------------------
public Choice getChoice(ModifiedObjectType type) {
if (choices!=null) {
for (Choice choice : choices) {
if (choice.type==type)
return choice;
}
}
return null;
}
//-------------------------------------------------------------------
public ModificationChoice getModificationChoice(UUID uuid) {
for (Modification tmp : modifications) {
if (tmp instanceof ModificationChoice && ((ModificationChoice)tmp).getUUID().equals(uuid))
return (ModificationChoice)tmp;
}
return null;
}
//-------------------------------------------------------------------
/**
* Override by specific implements (like AUGMENTATION_QUALITY fo SR6)
*/
protected Choice getHardcodedChoice(UUID uuid) {
return null;
}
//-------------------------------------------------------------------
public List getOutgoingModifications() {
return new ArrayList(modifications);
}
//-------------------------------------------------------------------
public void addOutgoingModifications(List value) {
this.modifications.addAll(value);
}
//-------------------------------------------------------------------
public List getRequirements() {
return requires;
}
//-------------------------------------------------------------------
public boolean hasLevel() {
return hasLevel;
}
//-------------------------------------------------------------------
public void setHasLevel(boolean hasLevel) {
this.hasLevel = hasLevel;
}
//-------------------------------------------------------------------
/**
* Used in deriving classes to perform validation checks on loading,
* if necessary
* @return Error message or NULL
*/
public void validate() throws DataErrorException {
super.validate();
for (Modification tmp : modifications) {
tmp.setSource(this);
}
// Validate modifications
try {
modifications.validate();
} catch (ReferenceException e) {
e.printStackTrace();
throw new DataErrorException(this, e.getError());
}
// Validate decisions in modifications
for (Modification tmp : modifications) {
if (tmp instanceof DataItemModification) {
DataItemModification mod = (DataItemModification)tmp;
Object resolved = null;
if (mod.getKey().startsWith("CHOICE:")) {
try {
String uuid_s = mod.getKey().substring(7);
UUID uuid = UUID.fromString(uuid_s);
} catch (Exception e) {
throw new DataErrorException(this, "Referring to decision must be 'CHOICE:'");
}
}
if (!"CHOICE".equals(mod.getKey()) && !mod.getKey().startsWith("CHOICE:")) {
resolved = mod.getReferenceType().resolve(mod.getKey());
}
ComplexDataItem item = (resolved instanceof ComplexDataItem)?(ComplexDataItem) resolved:null;
// Validate decisions
for (Decision dec : mod.getDecisions()) {
if (dec.getValue()!=null && dec.getValue().length()<3)
continue;
UUID uuid = dec.getChoiceUUID();
Choice choice = getChoice(uuid);
if (choice==null && item!=null)
choice = item.getChoice(uuid);
if (choice==null)
throw new DataErrorException(this, "Decision for non-existing choice "+uuid+" in item "+item);
// Before resolving, check if the reference is a UUID
try {
dec.setValueAsUUID( UUID.fromString(dec.getValue()) );
continue;
} catch (Exception e) {
}
resolved = choice.getChooseFrom().resolve(dec.getValue());
if (resolved==null) {
throw new ReferenceException(choice.getChooseFrom(), dec.getValue(), this);
}
}
}
}
// Validate requirements
try {
requires.validate();
} catch (ReferenceException e) {
throw new DataErrorException(this, e.getError());
}
// Choices in modifications must match available choices
for (Modification tmp : modifications) {
if (parentItem!=null)
tmp.setSource(parentItem);
else
tmp.setSource(this);
if (tmp instanceof DataItemModification) {
DataItemModification mod = (DataItemModification)tmp;
if ("CHOICE".equals(((DataItemModification) tmp).getKey())) {
// Is there a UUID for a choice given?
if (mod.getConnectedChoice()==null)
throw new DataErrorException(this, "Missing choice=\"\"");
// Is the UUID a valid choice UUID?
Choice choice = getChoice(mod.getConnectedChoice());
if (choice==null)
throw new DataErrorException(this, "No such choice "+mod.getConnectedChoice());
// Does the modification type match the choice type?
if (choice.getChooseFrom()!=mod.getReferenceType())
throw new DataErrorException(this, "Modification type "+mod.getReferenceType()+" does not match choice type "+choice.getChooseFrom());
}
}
}
// Choices
for (Choice tmp : choices) {
if (tmp.getChoiceOptions()!=null && tmp.getChoiceOptions().length>0) {
if (tmp.getTypeReference()==null)
tmp.setTypeReference("CHOICE");
// if (!tmp.getTypeReference().equals("CHOICE")) {
// throw new DataErrorException(this, "Choice "+tmp.getUUID()+" has options, so it should have ref=\"CHOICE\"");
// }
}
getChoiceName(tmp, Locale.getDefault());
if (!"SUBSELECT".equals(tmp.getChooseFrom().toString()))
continue;
String key = getTypeString()+"."+id.toLowerCase()+".choice."+tmp.ref.toLowerCase();
getLocalizedString(Locale.getDefault(), key);
for (ChoiceOption opt : tmp.getSubOptions()) {
opt.parentSet = this.parentSet;
opt.parent = this;
opt.choice = tmp;
getLocalizedString(Locale.getDefault(), key+"."+opt.getId());
getLocalizedString(Locale.getDefault(), key+"."+opt.getId()+".desc");
for (Modification m : opt.getOutgoingModifications()) {
m.setSource(this);
m.validate();
}
}
}
}
//-------------------------------------------------------------------
public void resolveWithinItem(Modification m) {
}
//-------------------------------------------------------------------
public String getChoiceName(Choice choice, Locale loc) {
List keys = new ArrayList();
if (choice==null && hasLevel) {
keys.add("choice.rating");
}
if (choice==null || choice.getChooseFrom()==null)
return "";
if (choice!=null && choice.getI18nKey()!=null)
keys.add("choice."+choice.getI18nKey());
String itemID = getTypeString()+"."+id.toLowerCase();
String parentID = (parentItem!=null)?(parentItem.getTypeString()+"."+parentItem.id.toLowerCase()):null;
String typeID = "choice."+String.valueOf(choice.getChooseFrom()).toLowerCase();
String choiceID = (choice.getTypeReference()!=null)?("choice."+choice.getTypeReference().toLowerCase()):"?";
if (choice.getTypeReference()!=null && choice.getTypeReference().equals("CHOICE"))
choiceID = String.valueOf(choice.getUUID());
if (parentItem!=null) {
keys.add(parentID+"."+itemID+"."+typeID+"."+choiceID);
keys.add(parentID+"."+itemID+"."+typeID);
keys.add(parentID+"."+itemID+"."+choiceID);
keys.add(parentID+"."+choiceID);
}
keys.add(itemID+"."+typeID+"."+choiceID);
keys.add( typeID+"."+choiceID);
keys.add(itemID+"."+typeID);
keys.add( typeID);
keys.add(itemID+"."+choiceID);
keys.add( choiceID);
return getLocalizedString(loc, keys);
}
//-------------------------------------------------------------------
public String getVariantName(PieceOfGearVariant> variant, Locale loc) {
String key = getTypeString()+"."+id.toLowerCase();
key+=".variant."+variant.getId();
if (variant.getGlobalI18NKey()!=null)
key = variant.getGlobalI18NKey();
return getLocalizedString(loc, key);
}
//-------------------------------------------------------------------
/**
* @param choice
* @param opt
* @param loc
* @return 0=Option name, 1=Option description
*/
public String[] getChoiceOptionStrings(Choice choice, ChoiceOption opt, Locale loc) {
if (opt==null)
throw new NullPointerException("ChoiceOption is null");
String key = getTypeString()+"."+id.toLowerCase()+".choice."+choice.ref.toLowerCase();
return new String[] {
getLocalizedString(loc, key+"."+opt.getId()),
getLocalizedString(loc, key+"."+opt.getId()+".desc")
};
}
//-------------------------------------------------------------------
public String getChoiceOptionString(Choice choice, HasName opt, Locale loc) {
if (opt==null)
throw new NullPointerException("ChoiceOption is null");
String key = getTypeString()+"."+id.toLowerCase()+".choice.";
if (choice.ref!=null)
key+=choice.ref.toLowerCase();
return getLocalizedString(loc, key+"."+opt.getId());
}
//-------------------------------------------------------------------
//@SuppressWarnings({ "unchecked", "rawtypes" })
public List getUserSelectableFlags(Class cls) {
List ret = new ArrayList<>();
for (String s : userSelectableFlags) {
T tmp = (T) Enum.valueOf(cls, s);
ret.add(tmp);
}
return ret;
// return userSelectableFlags.stream().map(s -> Enum.valueOf(cls, s)).collect(Collectors.toList());
}
//-------------------------------------------------------------------
public boolean hasUserSelectableFlag(ItemFlag flag) {
return userSelectableFlags.contains(flag.name());
}
//-------------------------------------------------------------------
public void addUserSelectableFlag(ItemFlag flag) {
if (!userSelectableFlags.contains(flag.name()))
this.userSelectableFlags.add(flag.name());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy