Skip to content

Commit

Permalink
devonfw#14: decoupling from mmm-util-entity (mmm-util-core is still u…
Browse files Browse the repository at this point in the history
…sed for exception/I18N stuff)

oasp/oasp4j#684: replaced AbstractJsonDeserializer with JacksonUtil
  • Loading branch information
hohwille committed Oct 4, 2018
1 parent ff86109 commit 76d59b6
Show file tree
Hide file tree
Showing 75 changed files with 885 additions and 625 deletions.
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= devon4jJava
= devon4j

The Java stack of http://devonfw.com[devonfw].

Expand Down
16 changes: 14 additions & 2 deletions modules/basic/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@
<description>Basic code for common usage (such as base classes for transfer objects) of the Open Application Standard Platform for Java (devon4j).</description>

<dependencies>
<!-- JPA only for JavaDoc links -->
<dependency>
<groupId>net.sf.m-m-m</groupId>
<artifactId>mmm-util-entity</artifactId>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring-Security for UserSessionAccess (default provider implementation) -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,47 @@
* within annotations).<br/>
* In test scenarios, these constants should be used in conjunction with the {@code @ActiveProfile} annotation.
*
* @since 2.2.0
* @since 3.0.0
*/
public class SpringProfileConstants {

/**
* This constant applies to all tests.
* Profile active in JUnit tests.
*/
public static final String JUNIT = "junit";

/**
* This constant denotes a live profile.
* Profile active if not in JUnit tests (on real application startup).
*/
public static final String NOT_JUNIT = "!" + JUNIT;

/**
* This constant should be used in conjunction with component tests.
* Profile active in local development environment.
*/
public static final String COMPONENT_TEST = "component-test";
public static final String DEV = "dev";

/**
* Profile active if not in local development environment ({@link #JUNIT} or real stages).
*/
public static final String NOT_DEV = "!" + DEV;

/**
* This constant should be used in conjunction with module tests.
* Profile for module tests.
*/
public static final String MODULE_TEST = "module-test";

/**
* This constant should be used in conjunction with subsystem tests.
* Profile for component tests.
*/
public static final String COMPONENT_TEST = "component-test";

/**
* Profile for subsystem tests.
*/
public static final String SUBSYSTEM_TEST = "subsystem-test";

/**
* This constant should be used in conjunction with system tests.
* Profile for system tests.
*/
public static final String SYSTEM_TEST = "system-test";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.devonfw.module.basic.common.api.entity;

import java.io.Serializable;

/**
* This is the interface for an entity, which is an object that is potentially stored in a persistent store (typically a
* database via JPA). Every non-abstract implementation of this interface is simply called an <em>entity</em>. It is
* supposed to be a simple java bean. <br>
* This interface makes the following assumptions:
* <ul>
* <li>A {@link GenericEntity} is identified by a {@link #getId() primary key}.</li>
* <li>A {@link GenericEntity} has a {@link #getModificationCounter() modification counter} for optimistic locking (even
* though not strictly required - you could statically return 0).</li>
* </ul>
* <b>ATTENTION:</b><br>
* An instance of this interface is typically one of the following:
* <ul>
* <li>a <b>JPA {@link javax.persistence.Entity}</b><br>
* <li>a <b>{@link com.devonfw.module.basic.common.api.to.AbstractEto entity transfer-object}</b><br>
* </ul>
* In order to distinguish the above cases an application has an architecture that organizes the code in technical
* layers (see <a href="http://en.wikipedia.org/wiki/Multilayered_architecture">multilayered architecture</a>) and
* business oriented slices (business components). Therefore within the persistence layer instances should always be
* {@link javax.persistence.Entity persistence entities}. On the other hand the higher layers always need to use
* {@link com.devonfw.module.basic.common.api.to.AbstractTo transfer-objects}. Our recommendation is to map between
* these two in the logic-layer using the {@code BeanMapper} component from the {@code devon4j-beanmapping} module.
*
* @see javax.persistence.Entity
*
* @param <ID> is the type of the {@link #getId() primary key}.
*
* @since 3.0.0
*/
public interface GenericEntity<ID> extends Serializable {

/**
* @return the primary key (unique identifier) of this entity. May be {@code null} if this entity is transient (not
* yet {@link javax.persistence.EntityManager#persist(Object) saved} in the database). While this method is
* initially defined in a generic way, it is strongly recommended to use {@link Long} as datatype for IDs.
* <br>
* Even if you want to have a {@link String}-based business-oriented identifier it is best practice to use a
* {@link Long} as primary key and add the business identifier as additional field (with a unique constraint).
* This way references to the entity will be a lot more compact and improve your performance in JOINs or the
* like. However, there may be reasons to use other datatypes for the ID. In any case the unique ID should be
* an immutable java-object that can be rebuild from its {@link Object#toString() string-representation}. <br>
* Please note that if your ID has a specific syntax, semantic, formatting rules, etc. you should create a
* custom datatype for it. If it can easily be mapped to a {@link Long} value you can still use {@link Long}
* here and provide a transient getter method that returns the your custom datatype from the {@link Long}.
* @see javax.persistence.Id
*/
ID getId();

/**
* @param id the new {@link #getId() primary key}. This method shall typically only be used by technical frameworks
* such as hibernate.
*/
void setId(ID id);

/**
* This method gets the current modification-counter of this entity. Whenever the object gets modified and
* {@link javax.persistence.EntityManager#persist(Object) persisted}, this counter will be increased (typically after
* the transaction is closed). The initial value after construction is {@code 0}. <br>
* This property is often simply called {@link javax.persistence.Version version}. However, as this sometimes causes
* confusion or may conflict with a business property "version", we use the more technical and self-explanatory name
* {@code modificationCounter}.<br>
* If this feature is NOT supported for some reason, this method should always return {@code 0}.
*
* @see javax.persistence.Version
*
* @return the current modification-counter.
* @see javax.persistence.Version
*/
int getModificationCounter();

/**
* @param modificationCounter the new {@link #getModificationCounter() modification counter}. This method shall
* typically only be used by technical frameworks such as hibernate.
*/
void setModificationCounter(int modificationCounter);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.devonfw.module.basic.common.api.entity;

/**
* This is the interface for a {@link GenericEntity} that is (potentially) revision-controlled. Frameworks like
* {@code hibernate-envers} (look for {@code @Audited} annotation on {@link javax.persistence.Entity JPA entities}) or
* {@code bi-temporal} can manage such entities so all changes are stored in the database as a revision history. An
* instance of this interface represents the {@link #getRevision() revision} of the {@link GenericEntity entity}. There
* are two cases to distinguish:
* <ul>
* <li><b>{@link #LATEST_REVISION latest revision}</b><br>
* A {@link RevisionedEntity} pointing to {@link #LATEST_REVISION} ({@code null}) represents the latest state of the
* entity and can be modified.</li>
* <li><b>historic {@link #getRevision() revision}</b><br>
* If the object is {@link #getRevision() revision controlled}, it has a history of modifications. A
* {@link RevisionedEntity} can represent a historic {@link #getRevision() revision} out of this history. It therefore
* is immutable so operations to modify the {@link RevisionedEntity} will typically fail.</li>
* </ul>
*
* @param <ID> is the type of the {@link #getId() primary key}.
*
* @since 3.0.0
*/
public interface RevisionedEntity<ID> extends GenericEntity<ID> {

/**
* The latest {@link #getRevision() revision} of an {@link GenericEntity entity}.
*/
Number LATEST_REVISION = null;

/**
* This method gets the revision of this entity. The {@link RevisionedEntity#LATEST_REVISION latest revision} of an
* entity will always return {@code null}. Otherwise this object is a <em>historic entity</em> and it will be
* read-only so modifications are NOT permitted.
*
* @return the revision or {@link #LATEST_REVISION} ({@code null}) if this is the latest revision.
*/
Number getRevision();

/**
* This method sets the {@link #getRevision() revision} of this entity. <br>
* <b>ATTENTION:</b><br>
* This operation should only be used in specific cases and if you are aware of what you are doing as this attribute
* is managed by the persistence. However, for final freedom we decided to add this method to the API (e.g. to copy
* from transfer-object to persistent-entity and vice-versa).
*
* @param revision is the new value of {@link #getRevision()}.
*/
void setRevision(Number revision);

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Generic implementation of {@link Ref}.
*
* @param <ID> generic type of {@link #getId() ID}.
* @param <E> generic type of the referenced {@link net.sf.mmm.util.entity.api.Entity}.
* @param <E> generic type of the referenced {@link com.devonfw.module.basic.common.api.entity.GenericEntity entity}.
*/
public class GenericIdRef<ID, E> implements Ref<ID, E> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.devonfw.module.basic.common.api.reference;

import net.sf.mmm.util.entity.api.GenericEntity;
import com.devonfw.module.basic.common.api.entity.GenericEntity;

/**
* A {@link Ref} using {@link Long} values as {@link #getId() ID}.
*
* @param <E> generic type of the referenced {@link net.sf.mmm.util.entity.api.Entity}.
* @param <E> generic type of the referenced {@link GenericEntity entity}.
*/
public class IdRef<E> extends GenericIdRef<Long, E> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.devonfw.module.basic.common.api.reference;

import net.sf.mmm.util.lang.api.Datatype;
import java.io.Serializable;

/**
* Interface for a reference to an {@link net.sf.mmm.util.entity.api.GenericEntity entity} via its {@link #getId() ID}.
* In most cases you want to use {@link IdRef}.
* Interface for a reference to an {@link com.devonfw.module.basic.common.api.entity.GenericEntity entity} via its
* {@link #getId() ID}. In most cases you want to use {@link IdRef}.
*
* @param <ID> generic type of {@link #getId() ID}.
* @param <E> generic type of the referenced {@link net.sf.mmm.util.entity.api.Entity}. For flexibility not technically
* bound to {@link net.sf.mmm.util.entity.api.Entity} so it can also be used for an external entity not
* satisfying any requirements.
* @param <E> generic type of the referenced {@link com.devonfw.module.basic.common.api.entity.GenericEntity entity}.
* For flexibility not technically bound to {@link com.devonfw.module.basic.common.api.entity.GenericEntity} so
* it can also be used for an external entity not satisfying any requirements.
*/
public interface Ref<ID, E> extends Datatype {
public interface Ref<ID, E> extends Serializable {

/**
* @return the ({@link net.sf.mmm.util.entity.api.GenericEntity#getId() ID} of the referenced
* {@link net.sf.mmm.util.entity.api.Entity}.
* @return the ({@link com.devonfw.module.basic.common.api.entity.GenericEntity#getId() ID} of the referenced
* {@link com.devonfw.module.basic.common.api.entity.GenericEntity entity}.
*/
ID getId();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package com.devonfw.module.basic.common.api.to;

import net.sf.mmm.util.transferobject.api.AbstractTransferObject;
import net.sf.mmm.util.transferobject.api.TransferObject;

/**
* This is the abstract base class for a composite {@link AbstractTo transfer-object}. Such object should contain
* (aggregate) other {@link AbstractTransferObject}s but no atomic data. This means it has properties that contain a
* {@link TransferObject} or a {@link java.util.Collection} of those but no {@link net.sf.mmm.util.lang.api.Datatype
* values}. <br>
* This is the abstract base class for a <em>CTO</em> (composite {@link AbstractTo transfer-object}). Such object should
* contain (aggregate) other {@link AbstractTo transfer-object}s or {@link java.util.Collection}s of those. However, a
* CTO shall never have properties for atomic data (datatypes).<br>
* Classes extending this class should carry the suffix <code>Cto</code>.
*
* @since 3.0.0
*/
public abstract class AbstractCto extends AbstractTo {

Expand Down
Loading

0 comments on commit 76d59b6

Please sign in to comment.