content: /*
   *  Licensed to the Apache Software Foundation (ASF) under one
   *  or more contributor license agreements.  See the NOTICE file
   *  distributed with this work for additional information
   *  regarding copyright ownership.  The ASF licenses this file
   *  to you under the Apache License, Version 2.0 (the
   *  "License"); you may not use this file except in compliance
   *  with the License.  You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing,
   *  software distributed under the License is distributed on an
   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   *  KIND, either express or implied.  See the License for the
   *  specific language governing permissions and limitations
   *  under the License.
   *
   */
  
  package org.apache.causeway.regressiontests.layouts.integtest.model;
  
  import java.util.Comparator;
  
  import jakarta.inject.Inject;
  import jakarta.inject.Named;
  import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  
  import org.apache.causeway.applib.annotation.Action;
  import org.apache.causeway.applib.annotation.ActionLayout;
  import org.apache.causeway.applib.annotation.DomainObject;
  import org.apache.causeway.applib.annotation.DomainObjectLayout;
  import org.apache.causeway.applib.annotation.PromptStyle;
  import org.apache.causeway.applib.annotation.Property;
  import org.apache.causeway.applib.annotation.PropertyLayout;
  import org.apache.causeway.applib.annotation.Publishing;
  import org.apache.causeway.applib.annotation.Title;
  import org.apache.causeway.applib.jaxb.PersistentEntityAdapter;
  import org.apache.causeway.applib.services.message.MessageService;
  import org.apache.causeway.applib.services.repository.RepositoryService;
  import org.apache.causeway.applib.services.title.TitleService;
  import org.apache.causeway.regressiontests.layouts.integtest.model.types.Name;
  import org.apache.causeway.regressiontests.layouts.integtest.model.types.Notes;
  
  import static org.apache.causeway.applib.annotation.SemanticsOf.IDEMPOTENT;
  import static org.apache.causeway.applib.annotation.SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE;
  
  import lombok.AccessLevel;
  import lombok.Getter;
  import lombok.NoArgsConstructor;
  import lombok.Setter;
  import lombok.ToString;
  
  @jakarta.persistence.Entity
  @jakarta.persistence.Table(
      schema="simple",
      uniqueConstraints = {
          @jakarta.persistence.UniqueConstraint(name = "SimpleObject__name__UNQ", columnNames = {"NAME"})
      }
  )
  @jakarta.persistence.NamedQueries({
          @jakarta.persistence.NamedQuery(
                  name = SimpleObject.NAMED_QUERY__FIND_BY_NAME_LIKE,
                  query = "SELECT so " +
                          "FROM SimpleObject so " +
                          "WHERE so.name LIKE :name"
          )
  })
  //@jakarta.persistence.EntityListeners(CausewayEntityListener.class)
  @DomainObject(entityChangePublishing = Publishing.ENABLED)
  @Named("simple.SimpleObject")
  @DomainObjectLayout()
  @NoArgsConstructor(access = AccessLevel.PUBLIC)
  @XmlJavaTypeAdapter(PersistentEntityAdapter.class)
  @ToString(onlyExplicitlyIncluded = true)
  public class SimpleObject implements Comparable<SimpleObject> {
  
      static final String NAMED_QUERY__FIND_BY_NAME_LIKE = "SimpleObject.findByNameLike";
  
      @jakarta.persistence.Id
      @jakarta.persistence.GeneratedValue(strategy = jakarta.persistence.GenerationType.AUTO)
      @jakarta.persistence.Column(name = "id", nullable = false)
      private Long id;
  
      @jakarta.persistence.Version
      @jakarta.persistence.Column(name = "version", nullable = false)
      @PropertyLayout(fieldSetId = "metadata", sequence = "999")
      @Getter @Setter
      private long version;
  
      public static SimpleObject withName(final String name) {
          var simpleObject = new SimpleObject();
          simpleObject.setName(name);
          return simpleObject;
      }
  
      @Inject @jakarta.persistence.Transient RepositoryService repositoryService;
      @Inject @jakarta.persistence.Transient TitleService titleService;
      @Inject @jakarta.persistence.Transient MessageService messageService;
  
      @Title
      @Name
      @jakarta.persistence.Column(length = Name.MAX_LEN, nullable = false)
      @Getter @Setter @ToString.Include
      @PropertyLayout(fieldSetId = "name", sequence = "1")
      private String name;
  
      @Notes
      @jakarta.persistence.Column(length = Notes.MAX_LEN, nullable = true)
      @Getter @Setter
      @Property(commandPublishing = Publishing.ENABLED, executionPublishing = Publishing.ENABLED)
      @PropertyLayout(fieldSetId = "name", sequence = "2")
      private String notes;
  
      @Action(semantics = IDEMPOTENT, commandPublishing = Publishing.ENABLED, executionPublishing = Publishing.ENABLED)
      @ActionLayout(associateWith = "name", promptStyle = PromptStyle.INLINE)
      public SimpleObject updateName(
              @Name final String name) {
          setName(name);
          return this;
      }
      public String default0UpdateName() {
          return getName();
      }
      public String validate0UpdateName(final String newName) {
          for (char prohibitedCharacter : "&%$!".toCharArray()) {
              if( newName.contains(""+prohibitedCharacter)) {
                  return "Character '" + prohibitedCharacter + "' is not allowed.";
              }
          }
          return null;
      }
  
      @Action(semantics = NON_IDEMPOTENT_ARE_YOU_SURE)
      @ActionLayout(
              position = ActionLayout.Position.PANEL,
              describedAs = "Deletes this object from the persistent datastore")
      public void delete() {
          final String title = titleService.titleOf(this);
          messageService.informUser(String.format("'%s' deleted", title));
          repositoryService.removeAndFlush(this);
      }
  
      private final static Comparator<SimpleObject> comparator =
              Comparator.comparing(SimpleObject::getName);
  
      @Override
      public int compareTo(final SimpleObject other) {
          return comparator.compare(this, other);
      }
  
  }
  