<commit_before>/*<license>
Copyright 2004 - $Date$ by PeopleWare n.v..

Licensed 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.
</license>*/

package org.ppwcode.vernacular.persistence_III.dao;


import static org.ppwcode.metainfo_I.License.Type.APACHE_V2;

import java.io.Serializable;
import java.util.Set;

import javax.ejb.Remote;

import org.ppwcode.metainfo_I.Copyright;
import org.ppwcode.metainfo_I.License;
import org.ppwcode.metainfo_I.vcs.SvnInfo;
import org.ppwcode.vernacular.exception_II.InternalException;
import org.ppwcode.vernacular.persistence_III.IdNotFoundException;
import org.ppwcode.vernacular.persistence_III.PersistentBean;
import org.ppwcode.vernacular.semantics_VI.bean.RousseauBean;
import org.toryt.annotations_I.Expression;
import org.toryt.annotations_I.MethodContract;
import org.toryt.annotations_I.Throw;


/**
 * <p>In contrast to the {@link AsyncCrudDao}, this {@link Dao} is stateless. This is done to make it possible to
 *   align transaction borders with method calls, which makes working with a remote implementation that much easier.
 *   Thus, for mutating methods (merge, delete), calling the method will result in the start of a transaction,
 *   the execution of the functionality, and a commit or roll-back. Failure is reported with exceptions according to
 *   the code exception vernacular.</p>
// MUDO
// * <p>Because a transaction that is atomic on the scale of the end user can be quite extensive, and include
// *   updates of existing entities, creation of new entities, and deletion of other entities, the create, update and
// *   delete functionality is also available gathered in 1 method
// *   -@link #writePersistentBeans(Set toBeCreated, Set toBeUpdated, Set toBeDeleted)}.
// *   User code should gather the {@link PersistentBean}s to be created, updated and deleted in a set, and then call
// *   this method to write information to persistent storage (possibly remotely). To support this stateful functionality,
// *   it might be appropriate to wrap an instance of this type in an {@link AsyncCrudDao} in user code.</p>
// END MUDO
 * <p>{@link #retrievePersistentBean(Class, Serializable)} and {@link #retrieveAllPersistentBeans(Class, boolean)}
 *   can be called outside a transaction. Objects that are deleted have their {@link PersistentBean#getPersistenceId()}
 *   set to {@code null}.</p>
 * <p>Before a {@link PersistentBean} is written to the persistent storage (see {@link #mergePersistentBean(PersistentBean)},
 *   it is {@link RousseauBean#normalize() normalized} and checked for {@link RousseauBean#civilized() civility}.</p>
 * <p>In throwing exceptions, we try to make a difference between programming errors, external exceptional conditions, and
 *   internal exceptional conditions. Semantic problems are certainly of the latter nature. But also the database can signal
 *   semantic problems (constraint violations mainly).</p>
 * <p>We understand that the limited functionality of this DAO cannot cope with the complete needs of persistence access.
 *   There is e.g., no notion of locking, e.g.. However, we do know from experience that this functionality covers a very
 *   large part of the needs, and that there are many applications that need no other functionality than this.</p>
 */
@Copyright("2004 - $Date$, PeopleWare n.v.")
@License(APACHE_V2)
@SvnInfo(revision = "$Revision$",
         date     = "$Date$")
@Remote
public interface StatelessCrudDao extends Dao {

  /**
   * <p>Return a persistent bean instance that represents the data of the record with key <code>id</code> of type
   *   <code>persistentBeanType</code> in the persistent storage.</p>
   * <p>Of particular note is the fact that returned beans <em>need not necessarily need to be civilized</em>.
   *   This is strange, and probably a bad practice, but we have encountered situations where our code
   *   needs to be more stringent (in creates and updates) than legacy data existing already in the database.</p>
   *
   * @idea (jand) security exceptions
   */
  @MethodContract(
    pre  = {
      @Expression("_persistentBeanType != null"),
      @Expression("_id != null")
    },
    post = {
      @Expression("result != null"),
      @Expression("result.id == _id")
    },
    exc = {
       @Throw(type = IdNotFoundException.class,
              cond = {
                @Expression(value = "true",
                            description = "no instance found in persistent storage with primary key 'id' " +
                                          "of type persistentBeanType"),
                @Expression("thrown.persistentBeanType == _persistentBeanType"),
                @Expression("thrown.id == _id")
              })
    }
  )
  <_Id_ extends Serializable, _PersistentBean_ extends PersistentBean<_Id_>>
  _PersistentBean_ retrievePersistentBean(final Class<_PersistentBean_> persistentBeanType, final _Id_ id) throws IdNotFoundException;

  /**
   * <p>Return the set of all persistent bean instances that represent the data of the records of type
   *   <code>persistentBeanType</code> in the persistent storage.</p>
   * <p>If this is too much data, consider using the {@link PagingList}.</p>
   * <p>Of particular note is the fact that returned beans <em>need not necessarily need to be civilized</em>.
   *   This is strange, and probably a bad practice, but we have encountered situations where our code
   *   needs to be more stringent (in creates and updates) than legacy data existing already in the database.</p>
   *
   * @param  retrieveSubClasses
   *         whether or not to also retrieve instances of subtypes of {@code persistentBeanType}; if
   *         {@code persistentBeanType} is  abstract, an empty set will be returned if {@code retrieveSubclasses}
   *         is false
   *
   * @idea (jand) security exceptions
   */
  @MethodContract(
    pre  = @Expression("_persistentBeanType != null"),
    post = {
      @Expression("result != null"),
      @Expression("! result.contains(null)"),
      @Expression("for (PersistentBean pb : result) {pb.id != null}")
    }
  )
  <_PersistentBean_ extends PersistentBean<?>>
  Set<_PersistentBean_> retrieveAllPersistentBeans(final Class<_PersistentBean_> persistentBeanType, final boolean retrieveSubClasses);

  /**
   * Create or update the object graph reachable from {@code pb}. Object with a {@link PersistentBean#getPersistenceId()} {@code null}
   * will be created, objects with an effective {@link PersistentBean#getPersistenceId()} will be updated. Note that not only {@code pb}
   * is created or updated, but all beans in the object graph that is reachable from {@code pb}, depending on the cascade settings.
   * This method is an atomic transaction.
   *
   * @mudo specific exception for rollback, or InternalException
   * @mudo contract
   */
  public <_Id_ extends Serializable, _PB_ extends PersistentBean<_Id_>> _PB_ mergePersistentBean(_PB_ pb) throws InternalException;

  /**
   * Delete the bean {@code pb}, and associated beans, depending on cascade settings.
   * The entire bean is returned, for reasons of consistency with the other methods.
   * This method is an atomic transaction.
   *
   * @mudo specific exception for rollback, or InternalException
   * @mudo contract
   */
  public <_Id_ extends Serializable, _PB_ extends PersistentBean<_Id_>> _PB_ deletePersistentBean(_PB_ pb) throws InternalException;

}<commit_msg>comments and other stuff cleaned for this version<commit_after>/*<license>
Copyright 2004 - $Date$ by PeopleWare n.v..

Licensed 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.
</license>*/

package org.ppwcode.vernacular.persistence_III.dao;


import static org.ppwcode.metainfo_I.License.Type.APACHE_V2;

import java.io.Serializable;
import java.util.Set;

import org.ppwcode.metainfo_I.Copyright;
import org.ppwcode.metainfo_I.License;
import org.ppwcode.metainfo_I.vcs.SvnInfo;
import org.ppwcode.vernacular.exception_II.InternalException;
import org.ppwcode.vernacular.exception_II.NoLongerSupportedError;
import org.ppwcode.vernacular.persistence_III.IdNotFoundException;
import org.ppwcode.vernacular.persistence_III.PersistentBean;
import org.ppwcode.vernacular.semantics_VI.bean.RousseauBean;
import org.toryt.annotations_I.Expression;
import org.toryt.annotations_I.MethodContract;
import org.toryt.annotations_I.Throw;


/**
 * <p>In contrast to the {@link AsyncCrudDao}, this {@link Dao} is stateless. This is done to make it possible to
 *   align transaction borders with method calls, which makes working with a remote implementation that much easier.
 *   Thus, for mutating methods (merge, delete), calling the method will result in the start of a transaction,
 *   the execution of the functionality, and a commit or roll-back. Failure is reported with exceptions according to
 *   the ppwcode exception vernacular.</p>
 * <p>Methods from this interface that change the persisted state work in their own separated transaction. When called
 *   within a transaction, the current transaction is suspended, and the method executes inside a new transaction that
 *   can commit successfully before returning on its own (~ requires new). When you need more synchronization with the
 *   rest of your algorithm, use another means of getting the same result (Local MUDO comes to mind :-) ).</p>
 * <p>{@link #retrievePersistentBean(Class, Serializable)} and {@link #retrieveAllPersistentBeans(Class, boolean)}
 *   can be called outside a transaction. Objects that are deleted have their {@link PersistentBean#getPersistenceId()}
 *   set to {@code null}.</p>
 * <p>Before a {@link PersistentBean} is written to the persistent storage (see {@link #mergePersistentBean(PersistentBean)},
 *   it is {@link RousseauBean#normalize() normalized} and checked for {@link RousseauBean#civilized() civility}. This entails
 *   also checking for civility of all upstream beans, either part of the submitted object graph, or already in the database.
 *   That way, wild conditions concerning collections of children (e.g., no period overlap for children in the collection)
 *   are enforced.</p>
 * <p>Do not expose this interface as part of the API in your business application directly. A better approach is to
 * <p>In throwing exceptions, we try to make a difference between programming errors, external exceptional conditions, and
 *   internal exceptional conditions. Semantic problems are certainly of the latter nature. But also the database can signal
 *   semantic problems (constraint violations mainly).</p>
 * <p>We understand that the limited functionality of this DAO cannot cope with the complete needs of persistence access.
 *   There is e.g., no notion of locking, e.g.. However, we do know from experience that this functionality covers a very
 *   large part of the needs, and that there are many applications that need no other functionality than this.</p>
 *   create an empty subtype in side a mark-version package, like this:</p>
 * <pre>
 *   package my.business.application_IV.businesslogic;
 *
 *   ...
 *
 *   &#64;Remote
 *   public StatelessCrudDao extends org.ppwcode.vernacular.persistence_III.dao.StatelessCrudDao {
 *
 *     // NOP
 *
 *   }
 * </pre>
 * <p>That is why this class does not have the {@code &#64;Remote} annotation (apart from infecting this library
 *   package with a dependency on EJB3 annotations). In this way you have the possibility to keep backward compatibility
 *   when your business application's semantics change, and the class / object model and data model change. In that case,
 *   you develop a new version in package {@code my.business.application_V}, introducing
 *   {@code my.business.application_V.businesslogic.StatelessCrudDao}. With that, your clients can now choose which version they
 *   want to use. From the old version, you keep the necessary classes, but since the database structure probably has changed,
 *   retrieving and updating data cannot easily happen the same way. In particular, your semantics (persistent bean subtypes)
 *   will probably no longer map to the database. This means that your original implementation of
 *   {@code my.business.application_IV.businesslogic.StatelessCrudDao} with the old semantics (entities) will no longer work.
 *   By changing the implementation of {@code my.business.application_IV.businesslogic.StatelessCrudDao} to map
 *   old semantic POJO's (now no longer entities) to new entities (if at all possible), you make the new semantics backward
 *   compatible with the old interface. Because this is not always possible with all methods of this interface in all
 *   circumstances, all methods can throw a {@link NoLongerSupportedError}.</p>
 *
 *
// MUDO
// * <p>Because a transaction that is atomic on the scale of the end user can be quite extensive, and include
// *   updates of existing entities, creation of new entities, and deletion of other entities, the create, update and
// *   delete functionality is also available gathered in 1 method
// *   -@link #writePersistentBeans(Set toBeCreated, Set toBeUpdated, Set toBeDeleted)}.
// *   User code should gather the {@link PersistentBean}s to be created, updated and deleted in a set, and then call
// *   this method to write information to persistent storage (possibly remotely). To support this stateful functionality,
// *   it might be appropriate to wrap an instance of this type in an {@link AsyncCrudDao} in user code.</p>
// END MUDO
 */
@Copyright("2004 - $Date$, PeopleWare n.v.")
@License(APACHE_V2)
@SvnInfo(revision = "$Revision$",
         date     = "$Date$")
public interface StatelessCrudDao extends Dao {

  /**
   * <p>Return a persistent bean instance that represents the data of the record with key <code>id</code> of type
   *   <code>persistentBeanType</code> in the persistent storage.</p>
   * <p>Of particular note is the fact that returned beans <em>need not necessarily need to be civilized</em>.
   *   This is strange, and probably a bad practice, but we have encountered situations where our code
   *   needs to be more stringent (in creates and updates) than legacy data existing already in the database.</p>
   *
   * @idea (jand) security exceptions
   */
  @MethodContract(
    pre  = {
      @Expression("_persistentBeanType != null"),
      @Expression("_id != null")
    },
    post = {
      @Expression("result != null"),
      @Expression("result.id == _id")
    },
    exc = {
       @Throw(type = IdNotFoundException.class,
              cond = {
                @Expression(value = "true",
                            description = "no instance found in persistent storage with primary key 'id' " +
                                          "of type persistentBeanType"),
                @Expression("thrown.persistentBeanType == _persistentBeanType"),
                @Expression("thrown.id == _id")
              }),
       @Throw(type = NoLongerSupportedError.class,
              cond = {@Expression("true")})
    }
  )
  <_Id_ extends Serializable, _PersistentBean_ extends PersistentBean<_Id_>>
  _PersistentBean_ retrievePersistentBean(final Class<_PersistentBean_> persistentBeanType, final _Id_ id) throws IdNotFoundException, NoLongerSupportedError;

  /**
   * <p>Return the set of all persistent bean instances that represent the data of the records of type
   *   <code>persistentBeanType</code> in the persistent storage.</p>
   * <p>If this is too much data, consider using the {@link PagingList}.</p>
   * <p>Of particular note is the fact that returned beans <em>need not necessarily need to be civilized</em>.
   *   This is strange, and probably a bad practice, but we have encountered situations where our code
   *   needs to be more stringent (in creates and updates) than legacy data existing already in the database.</p>
   *
   * @param  retrieveSubClasses
   *         whether or not to also retrieve instances of subtypes of {@code persistentBeanType}; if
   *         {@code persistentBeanType} is  abstract, an empty set will be returned if {@code retrieveSubclasses}
   *         is false
   *
   * @idea (jand) security exceptions
   */
  @MethodContract(
    pre  = @Expression("_persistentBeanType != null"),
    post = {
      @Expression("result != null"),
      @Expression("! result.contains(null)"),
      @Expression("for (PersistentBean pb : result) {pb.id != null}")
    },
    exc  =  @Throw(type = NoLongerSupportedError.class,
                   cond = {@Expression("true")})
  )
  <_PersistentBean_ extends PersistentBean<?>>
  Set<_PersistentBean_> retrieveAllPersistentBeans(final Class<_PersistentBean_> persistentBeanType, final boolean retrieveSubClasses) throws NoLongerSupportedError;

  /**
   * Create or update the object graph reachable from {@code pb}. Object with a {@link PersistentBean#getPersistenceId()} {@code null}
   * will be created, objects with an effective {@link PersistentBean#getPersistenceId()} will be updated. Note that not only {@code pb}
   * is created or updated, but all beans in the object graph that is reachable from {@code pb}, depending on the cascade settings.
   * This method is an atomic transaction. Any exception that is thrown signals a roll-back of the transaction. If the methods ends nominally,
   * the transaction is successfully committed.
   *
   * @mudo specific exception for rollback, or InternalException
   * @mudo contract
   * @idea (jand) security exceptions
   */
  @MethodContract(
    post = {},
    exc  =  @Throw(type = NoLongerSupportedError.class,
                   cond = {@Expression("true")})
  )
  public <_Id_ extends Serializable, _PB_ extends PersistentBean<_Id_>> _PB_ mergePersistentBean(_PB_ pb) throws InternalException, NoLongerSupportedError;

  /**
   * Delete the bean {@code pb}, and associated beans, depending on cascade settings.
   * The entire bean is returned, for reasons of consistency with the other methods.
   * This method is an atomic transaction. Any exception that is thrown signals a roll-back of the transaction. If the methods ends nominally,
   * the transaction is successfully committed.
   *
   * @mudo specific exception for rollback, or InternalException
   * @mudo contract
   * @idea (jand) security exceptions
   */
  @MethodContract(
    post = {},
    exc  =  @Throw(type = NoLongerSupportedError.class,
                   cond = {@Expression("true")})
  )
  public <_Id_ extends Serializable, _PB_ extends PersistentBean<_Id_>> _PB_ deletePersistentBean(_PB_ pb) throws InternalException, NoLongerSupportedError;

}
{'fraction_non_alphanumeric': 0.08453671822806927, 'fraction_numerical': 0.0017986535793206228, 'mean_word_length': 3.848031888390633, 'pattern_counts': {'":': 0, '<': 101, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6083390', 'n_tokens_mistral': 5193, 'n_tokens_neox': 5103, 'n_words': 2146}