
package de.ivu.elect.business.personenregister.entity;

import static java.util.Arrays.asList;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.convert.Converter;

import de.ivu.elect.business.person.entity.Geschlecht;
import de.ivu.elect.business.person.entity.Sperrmerkmal;
import de.ivu.elect.business.person.entity.Wahlrechtsausschluss;
import de.ivu.elect.jee.presentation.dynamicform.AbstractBooleanProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractDateProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.converter.AutoFormatDateTimeConverter;

public class PersonenregisterPersonendatenProperties implements Serializable {

  private static final long serialVersionUID = 1L;

  private final PersonenregisterPersonendaten personenregisterPersonendaten;

  private transient OrdnungsmerkmalProperty ordnungsmerkmalProperty;

  private transient AnredeProperty anredeProperty;

  private transient TitelProperty titelProperty;

  private transient FamiliennameProperty familiennameProperty;

  private transient FamiliennameBestandteilProperty familiennameBestandteilProperty;

  private transient RufnameProperty rufnameProperty;

  private transient VornamenProperty vornamenProperty;

  private transient KuenstlernameProperty kuenstlernameProperty;

  private transient OrdensnameProperty ordensnameProperty;

  private transient GeburtsdatumProperty geburtsdatumProperty;

  private transient GeburtsortProperty geburtsortProperty;

  private transient GeschlechtProperty geschlechtProperty;

  private transient List<NameOrCodeStaatsangehoerigkeitProperty> nameOrCodeStaatsangehoerigkeitProperties;

  private transient EinwohnerstatusProperty einwohnerstatusProperty;

  private transient SperrmerkmalProperty sperrmerkmalProperty;

  private transient WahlrechtsausschlussProperty wahlrechtsausschlussProperty;

  private transient StimmbezirkSchluesselProperty stimmbezirkSchluesselProperty;

  private transient ZuzugsdatumBundProperty zuzugsdatumBundProperty;

  private transient ZuzugsdatumLandProperty zuzugsdatumLandProperty;

  private transient ZuzugsdatumGemeindeProperty zuzugsdatumGemeindeProperty;

  private transient ZuzugsdatumStadtbezirkProperty zuzugsdatumStadtbezirkProperty;

  public PersonenregisterPersonendatenProperties(PersonenregisterPersonendaten personenregisterPersonendaten) {
    super();

    this.personenregisterPersonendaten = personenregisterPersonendaten;
  }

  public OrdnungsmerkmalProperty getOrdnungsmerkmalProperty() {
    if (ordnungsmerkmalProperty == null) {
      ordnungsmerkmalProperty = new OrdnungsmerkmalProperty(personenregisterPersonendaten);
    }

    return ordnungsmerkmalProperty;
  }

  public AnredeProperty getAnredeProperty() {
    if (anredeProperty == null) {
      anredeProperty = new AnredeProperty(personenregisterPersonendaten);
    }

    return anredeProperty;
  }

  public TitelProperty getTitelProperty() {
    if (titelProperty == null) {
      titelProperty = new TitelProperty(personenregisterPersonendaten);
    }

    return titelProperty;
  }

  public FamiliennameProperty getFamiliennameProperty() {
    if (familiennameProperty == null) {
      familiennameProperty = new FamiliennameProperty(personenregisterPersonendaten);
    }

    return familiennameProperty;
  }

  public FamiliennameBestandteilProperty getFamiliennameBestandteilProperty() {
    if (familiennameBestandteilProperty == null) {
      familiennameBestandteilProperty = new FamiliennameBestandteilProperty(personenregisterPersonendaten);
    }

    return familiennameBestandteilProperty;
  }

  public RufnameProperty getRufnameProperty() {
    if (rufnameProperty == null) {
      rufnameProperty = new RufnameProperty(personenregisterPersonendaten);
    }

    return rufnameProperty;
  }

  public VornamenProperty getVornamenProperty() {
    if (vornamenProperty == null) {
      vornamenProperty = new VornamenProperty(personenregisterPersonendaten);
    }

    return vornamenProperty;
  }

  public KuenstlernameProperty getKuenstlernameProperty() {
    if (kuenstlernameProperty == null) {
      kuenstlernameProperty = new KuenstlernameProperty(personenregisterPersonendaten);
    }

    return kuenstlernameProperty;
  }

  public OrdensnameProperty getOrdensnameProperty() {
    if (ordensnameProperty == null) {
      ordensnameProperty = new OrdensnameProperty(personenregisterPersonendaten);
    }

    return ordensnameProperty;
  }

  public GeburtsdatumProperty getGeburtsdatumProperty() {
    if (geburtsdatumProperty == null) {
      geburtsdatumProperty = new GeburtsdatumProperty(personenregisterPersonendaten);
    }

    return geburtsdatumProperty;
  }

  public GeburtsortProperty getGeburtsortProperty() {
    if (geburtsortProperty == null) {
      geburtsortProperty = new GeburtsortProperty(personenregisterPersonendaten);
    }

    return geburtsortProperty;
  }

  public GeschlechtProperty getGeschlechtProperty() {
    if (geschlechtProperty == null) {
      geschlechtProperty = new GeschlechtProperty(personenregisterPersonendaten);
    }

    return geschlechtProperty;
  }

  public List<NameOrCodeStaatsangehoerigkeitProperty> getNameOrCodeStaatsangehoerigkeitProperties() {
    if (nameOrCodeStaatsangehoerigkeitProperties == null) {
      nameOrCodeStaatsangehoerigkeitProperties = new ArrayList<>();

      for (String staatsangehoerigkeit : personenregisterPersonendaten.getStaatsangehoerigkeiten()) {
        // Standardmäßig wird zumindest der externe Code zur Staatsangehörigkeit angezeigt und kann ggf. im View überschrieben werden!
        nameOrCodeStaatsangehoerigkeitProperties.add(new NameOrCodeStaatsangehoerigkeitProperty(personenregisterPersonendaten, staatsangehoerigkeit));
      }

      if (nameOrCodeStaatsangehoerigkeitProperties.isEmpty()) {
        nameOrCodeStaatsangehoerigkeitProperties.add(new NameOrCodeStaatsangehoerigkeitProperty(personenregisterPersonendaten, ""));
      }
    }

    return nameOrCodeStaatsangehoerigkeitProperties;
  }

  public EinwohnerstatusProperty getEinwohnerstatusProperty() {
    if (einwohnerstatusProperty == null) {
      einwohnerstatusProperty = new EinwohnerstatusProperty(personenregisterPersonendaten);
    }

    return einwohnerstatusProperty;
  }

  public SperrmerkmalProperty getSperrmerkmalProperty() {
    if (sperrmerkmalProperty == null) {
      sperrmerkmalProperty = new SperrmerkmalProperty(personenregisterPersonendaten);
    }

    return sperrmerkmalProperty;
  }

  public WahlrechtsausschlussProperty getWahlrechtsausschlussProperty() {
    if (wahlrechtsausschlussProperty == null) {
      wahlrechtsausschlussProperty = new WahlrechtsausschlussProperty(personenregisterPersonendaten);
    }

    return wahlrechtsausschlussProperty;
  }

  public StimmbezirkSchluesselProperty getStimmbezirkSchluesselProperty() {
    if (stimmbezirkSchluesselProperty == null) {
      stimmbezirkSchluesselProperty = new StimmbezirkSchluesselProperty(personenregisterPersonendaten);
    }

    return stimmbezirkSchluesselProperty;
  }

  public ZuzugsdatumBundProperty getZuzugsdatumBundProperty() {
    if (zuzugsdatumBundProperty == null) {
      zuzugsdatumBundProperty = new ZuzugsdatumBundProperty(personenregisterPersonendaten);
    }

    return zuzugsdatumBundProperty;
  }

  public ZuzugsdatumLandProperty getZuzugsdatumLandProperty() {
    if (zuzugsdatumLandProperty == null) {
      zuzugsdatumLandProperty = new ZuzugsdatumLandProperty(personenregisterPersonendaten);
    }

    return zuzugsdatumLandProperty;
  }

  public ZuzugsdatumGemeindeProperty getZuzugsdatumGemeindeProperty() {
    if (zuzugsdatumGemeindeProperty == null) {
      zuzugsdatumGemeindeProperty = new ZuzugsdatumGemeindeProperty(personenregisterPersonendaten);
    }

    return zuzugsdatumGemeindeProperty;
  }

  public ZuzugsdatumStadtbezirkProperty getZuzugsdatumStadtbezirkProperty() {
    if (zuzugsdatumStadtbezirkProperty == null) {
      zuzugsdatumStadtbezirkProperty = new ZuzugsdatumStadtbezirkProperty(personenregisterPersonendaten);
    }

    return zuzugsdatumStadtbezirkProperty;
  }

  public static class OrdnungsmerkmalProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public OrdnungsmerkmalProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getOrdnungsmerkmal();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.ORDNUNGSMERKMAL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ORDNUNGSMERKMAL_EINZAHL);
    }
  }

  public static class AnredeProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public AnredeProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getAnrede();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.ANREDE_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ANREDE_EINZAHL);
    }
  }

  public static class TitelProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public TitelProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getTitel();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.TITEL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_TITEL_EINZAHL);
    }
  }

  public static class FamiliennameProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public FamiliennameProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getFamilienname();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.FAMILIENNAME_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_FAMILIENNAME_EINZAHL);
    }
  }

  public static class RufnameProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public RufnameProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getRufname();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.RUFNAME_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_RUFNAME_EINZAHL);
    }
  }

  public static class VornamenProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public VornamenProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getVornamen();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.VORNAMEN_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_VORNAMEN_EINZAHL);
    }
  }

  public static class FamiliennameBestandteilProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public FamiliennameBestandteilProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getFamiliennameBestandteil();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.FAMILIENNAME_BESTANDTEIL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_FAMILIENNAME_BESTANDTEIL_EINZAHL);
    }
  }

  public static class KuenstlernameProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public KuenstlernameProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getKuenstlername();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.KUENSTLERNAME_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_KUENSTLERNAME_EINZAHL);
    }
  }

  public static class OrdensnameProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public OrdensnameProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getOrdensname();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.ORDENSNAME_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ORDENSNAME_EINZAHL);
    }
  }

  public static class GeburtsdatumProperty extends AbstractPersonenregisterPersonendatenDateProperty {

    public GeburtsdatumProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Date getValue() {
      return getPersonenregisterPersonendaten().getGeburtsdatum();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_GEBURTSDATUM_EINZAHL);
    }

    @Override
    public Converter getDefaultConverter() {
      return new AutoFormatDateTimeConverter(true); // ELECTMUC-2429
    }
  }

  public static class GeburtsortProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public GeburtsortProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getGeburtsort();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.GEBURTSORT_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_GEBURTSORT_EINZAHL);
    }
  }

  public static class GeschlechtProperty extends AbstractPersonenregisterPersonendatenEnumProperty<Geschlecht> {

    public GeschlechtProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Geschlecht getValue() {
      return getPersonenregisterPersonendaten().getGeschlecht();
    }

    @Override
    public List<Geschlecht> getValues() {
      return asList(Geschlecht.values());
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_GESCHLECHT_EINZAHL);
    }

    @Override
    public Class<Geschlecht> getEnumClass() {
      return Geschlecht.class;
    }
  }

  public static class NameOrCodeStaatsangehoerigkeitProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    private final String codeStaatsangehoerigkeit;

    private String nameStaatsangehoerigkeit;

    public NameOrCodeStaatsangehoerigkeitProperty(PersonenregisterPersonendaten personenregisterPersonendaten, String codeStaatsangehoerigkeit) {
      super(personenregisterPersonendaten);

      this.codeStaatsangehoerigkeit = codeStaatsangehoerigkeit;
    }

    public String getCodeStaatsangehoerigkeit() {
      return codeStaatsangehoerigkeit;
    }

    private boolean hasNameStaatsangehoerigkeit() {
      return isNotBlank(getNameStaatsangehoerigkeit());
    }

    public String getNameStaatsangehoerigkeit() {
      return nameStaatsangehoerigkeit;
    }

    public void setNameStaatsangehoerigkeit(String nameStaatsangehoerigkeit) {
      this.nameStaatsangehoerigkeit = nameStaatsangehoerigkeit;
    }

    @Override
    public String getValue() {
      if (hasNameStaatsangehoerigkeit()) {
        return getNameStaatsangehoerigkeit();
      }

      return getCodeStaatsangehoerigkeit();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.NAME_OR_CODE_STAATSANGEHOERIGKEIT_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_NAME_OR_CODE_STAATSANGEHOERIGKEIT_EINZAHL);
    }
  }

  public static class EinwohnerstatusProperty extends AbstractPersonenregisterPersonendatenEnumProperty<PersonenregisterEinwohnerstatus> {

    public EinwohnerstatusProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public PersonenregisterEinwohnerstatus getValue() {
      return getPersonenregisterPersonendaten().getEinwohnerstatus();
    }

    @Override
    public List<PersonenregisterEinwohnerstatus> getValues() {
      return asList(PersonenregisterEinwohnerstatus.values());
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_EINWOHNERSTATUS_EINZAHL);
    }

    @Override
    public Class<PersonenregisterEinwohnerstatus> getEnumClass() {
      return PersonenregisterEinwohnerstatus.class;
    }
  }

  public static class SperrmerkmalProperty extends AbstractPersonenregisterPersonendatenEnumProperty<Sperrmerkmal> {

    public SperrmerkmalProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Sperrmerkmal getValue() {
      return getPersonenregisterPersonendaten().getSperrmerkmal();
    }

    @Override
    public List<Sperrmerkmal> getValues() {
      return Sperrmerkmal.valuesSorted();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_SPERRMERKMAL_EINZAHL);
    }

    @Override
    public Class<Sperrmerkmal> getEnumClass() {
      return Sperrmerkmal.class;
    }
  }

  public static class WahlrechtsausschlussProperty extends AbstractPersonenregisterPersonendatenEnumProperty<Wahlrechtsausschluss> {

    public WahlrechtsausschlussProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Wahlrechtsausschluss getValue() {
      return getPersonenregisterPersonendaten().getWahlrechtsausschluss();
    }

    @Override
    public List<Wahlrechtsausschluss> getValues() {
      return Wahlrechtsausschluss.valuesSorted();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_WAHLRECHTSAUSSCHLUSS_EINZAHL);
    }

    @Override
    public Class<Wahlrechtsausschluss> getEnumClass() {
      return Wahlrechtsausschluss.class;
    }
  }

  public static class StimmbezirkSchluesselProperty extends AbstractPersonenregisterPersonendatenStringProperty {

    public StimmbezirkSchluesselProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public String getValue() {
      return getPersonenregisterPersonendaten().getStimmbezirkSchluessel();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterPersonendatenConstants.STIMMBEZIRK_SCHLUESSEL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_STIMMBEZIRK_SCHLUESSEL_EINZAHL);
    }
  }

  public static class ZuzugsdatumBundProperty extends AbstractPersonenregisterPersonendatenDateProperty {

    public ZuzugsdatumBundProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Date getValue() {
      return getPersonenregisterPersonendaten().getZuzugsdatumBund();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ZUZUGSDATUM_BUND_EINZAHL);
    }
  }

  public static class ZuzugsdatumLandProperty extends AbstractPersonenregisterPersonendatenDateProperty {

    public ZuzugsdatumLandProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Date getValue() {
      return getPersonenregisterPersonendaten().getZuzugsdatumLand();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ZUZUGSDATUM_LAND_EINZAHL);
    }
  }

  public static class ZuzugsdatumGemeindeProperty extends AbstractPersonenregisterPersonendatenDateProperty {

    public ZuzugsdatumGemeindeProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Date getValue() {
      return getPersonenregisterPersonendaten().getZuzugsdatumGemeinde();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ZUZUGSDATUM_GEMEINDE_EINZAHL);
    }
  }

  public static class ZuzugsdatumStadtbezirkProperty extends AbstractPersonenregisterPersonendatenDateProperty {

    public ZuzugsdatumStadtbezirkProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super(personenregisterPersonendaten);
    }

    @Override
    public Date getValue() {
      return getPersonenregisterPersonendaten().getZuzugsdatumStadtbezirk();
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterPersonendatenConstants.MESSAGE_KEY_ZUZUGSDATUM_STADTBEZIRK_EINZAHL);
    }
  }

  protected abstract static class AbstractPersonenregisterPersonendatenDateProperty extends AbstractDateProperty {

    protected final PersonenregisterPersonendaten personenregisterPersonendaten;

    protected AbstractPersonenregisterPersonendatenDateProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super();

      this.personenregisterPersonendaten = personenregisterPersonendaten;
    }

    protected PersonenregisterPersonendaten getPersonenregisterPersonendaten() {
      return personenregisterPersonendaten;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public void setValue(Date value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }

  protected abstract static class AbstractPersonenregisterPersonendatenStringProperty extends AbstractStringProperty {

    protected final PersonenregisterPersonendaten personenregisterPersonendaten;

    public AbstractPersonenregisterPersonendatenStringProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super();

      this.personenregisterPersonendaten = personenregisterPersonendaten;
    }

    protected PersonenregisterPersonendaten getPersonenregisterPersonendaten() {
      return personenregisterPersonendaten;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public void setValue(String value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }

  protected abstract static class AbstractPersonenregisterPersonendatenEnumProperty<E extends Enum<E>> extends AbstractEnumProperty<E> {

    protected final PersonenregisterPersonendaten personenregisterPersonendaten;

    public AbstractPersonenregisterPersonendatenEnumProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super();

      this.personenregisterPersonendaten = personenregisterPersonendaten;
    }

    protected PersonenregisterPersonendaten getPersonenregisterPersonendaten() {
      return personenregisterPersonendaten;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public void setValue(E value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }

  protected abstract static class AbstractPersonenregisterPersonendatenBooleanProperty extends AbstractBooleanProperty {

    protected final PersonenregisterPersonendaten personenregisterPersonendaten;

    public AbstractPersonenregisterPersonendatenBooleanProperty(PersonenregisterPersonendaten personenregisterPersonendaten) {
      super();

      this.personenregisterPersonendaten = personenregisterPersonendaten;
    }

    protected PersonenregisterPersonendaten getPersonenregisterPersonendaten() {
      return personenregisterPersonendaten;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public void setValue(Boolean value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }
}
