Skip to content

Commit

Permalink
#181: added Id
Browse files Browse the repository at this point in the history
#177: improved
#163: improved
  • Loading branch information
hohwille committed May 1, 2016
1 parent abf047e commit 490c891
Show file tree
Hide file tree
Showing 82 changed files with 2,714 additions and 227 deletions.
55 changes: 55 additions & 0 deletions mmm-util-core/src/main/java/net/sf/mmm/util/lang/api/Id.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.lang.api;

/**
* This is the interface for an ID that uniquely identifies an <em>entity</em> of a particular type.<br>
* An {@link Id} is build out of the following parts:
* <ul>
* <li>{@link #getId() object-id} - the ID that identifies the entity and is unique for a specific {@link #getType()
* type}.</li>
* <li>{@link #getType() type} - is the ID of the type of the identified entity.</li>
* <li>{@link #getRevision() revision} - the optional {@link #getRevision() revision} of the entity.</li>
* </ul>
* Just like the {@link #getId() primary key} the {@link #getRevision() revision} and {@link #getType() type} of an
* object do not change. This allows to create an instance of the identified object without additional costs (e.g.
* database lookup) by a dynamic proxy using lazy loading.<br>
* An {@link Id} has a compact {@link #toString() string representation} that can be converted back to an {@link Id}.
* Therefore, the implementation shall provide a {@link String}-arg constructor and a static {@code valueOf(String)}
* method.
*
* @param <E> the generic type of the identified entity.
*
* @see net.sf.mmm.util.lang.base.SimpleId
* @author hohwille
* @since 7.1.0
*/
public interface Id<E> extends Datatype {

/**
* @return the the <em>primary key</em> of the <em>entity</em>. It is only unique for a particular {@link #getType()
* type} of an <em>entity</em>.
*/
long getId();

/**
* @return the {@link Class} reflecting the <em>type</em> of the referenced <em>entity</em>.
*/
Class<E> getType();

/**
* @return the optional revision of the <em>entity</em> referenced by this {@link Id} or {@code null} for the latest
* revision. In case entities of this {@link #getType() type} will not be revision controlled, this method
* will always return {@code null}.
*/
Number getRevision();

/**
* @return the {@link String} representation of this {@link Id}. Will consist of {@link #getId() object-id},
* {@link #getType() type} and {@link #getRevision() revision} separated with a specific separator. Segments
* that are {@code null} will typically be omitted in the {@link String} representation.
*/
@Override
String toString();

}
128 changes: 128 additions & 0 deletions mmm-util-core/src/main/java/net/sf/mmm/util/lang/base/AbstractId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.lang.base;

import java.util.Objects;

import net.sf.mmm.util.lang.api.Id;

/**
* This is the abstract base implementation of {@link Id}.
*
* @param <E> the generic type of the identified entity.
*
* @author hohwille
* @since 7.1.0
*/
public abstract class AbstractId<E> implements Id<E> {

private long objectId;

private Number revision;

private Class<E> type;

/**
* The constructor.
*/
protected AbstractId() {
super();
}

/**
* The constructor.
*
* @param type - see {@link #getType()}.
* @param objectId - see {@link #getId()}.
*/
public AbstractId(Class<E> type, long objectId) {
this(type, objectId, null);
}

/**
* The constructor.
*
* @param type - see {@link #getType()}.
* @param objectId - see {@link #getId()}.
* @param revision - see {@link #getRevision()}.
*/
public AbstractId(Class<E> type, long objectId, Number revision) {
super();
this.type = type;
this.objectId = objectId;
this.revision = revision;
}

@Override
public long getId() {

return this.objectId;
}

@Override
public Class<E> getType() {

return this.type;
}

@Override
public Number getRevision() {

return this.revision;
}

@Override
public final int hashCode() {

return Objects.hash(Long.valueOf(this.objectId), this.type, this.revision);
}

@Override
public final boolean equals(Object obj) {

if (obj == this) {
return true;
}
if ((obj == null) || !(obj instanceof AbstractId)) {
return false;
}
AbstractId<?> other = (AbstractId<?>) obj;
if (this.objectId != other.objectId) {
return false;
}
if (!Objects.equals(this.type, other.type)) {
return false;
}
if (!Objects.equals(this.revision, other.revision)) {
return false;
}
return true;
}

@Override
public String toString() {

StringBuilder buffer = new StringBuilder(32);
toString(buffer);
return buffer.toString();
}

/**
* @see #toString()
* @param buffer the {@link StringBuilder} where to {@link StringBuilder#append(CharSequence) append} the string
* representation to.
*/
protected void toString(StringBuilder buffer) {

if (this.type != null) {
buffer.append(this.type.getSimpleName());
buffer.append(':');
}
buffer.append(this.objectId);
if (this.revision != null) {
buffer.append(':');
buffer.append(this.revision);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.lang.base;

import javax.persistence.Id;

/**
* This is a simple implementation of {@link Id}.
*
* @param <E> the generic type of the identified entity.
*
* @author hohwille
* @since 7.1.0
*/
public class SimpleId<E> extends AbstractId<E> {

/**
* The constructor.
*/
protected SimpleId() {
super();
}

/**
* The constructor.
*
* @param type - see {@link #getType()}.
* @param objectId - see {@link #getId()}.
*/
public SimpleId(Class<E> type, long objectId) {
this(type, objectId, null);
}

/**
* The constructor.
*
* @param type - see {@link #getType()}.
* @param objectId - see {@link #getId()}.
* @param revision - see {@link #getRevision()}.
*/
public SimpleId(Class<E> type, long objectId, Number revision) {
super(type, objectId, revision);
}

/**
* @param <E> the generic type of the identified entity.
* @param type - see {@link #getType()}.
* @param id - see {@link #getId()}.
* @return a new instance of {@link SimpleId}.
*/
public static <E> SimpleId<E> valueOf(Class<E> type, Long id) {

return valueOf(type, id, null);
}

/**
* @param <E> the generic type of the identified entity.
* @param type - see {@link #getType()}.
* @param id - see {@link #getId()}.
* @param revision - see {@link #getRevision()}.
* @return a new instance of {@link SimpleId}.
*/
public static <E> SimpleId<E> valueOf(Class<E> type, Long id, Number revision) {

if (id == null) {
return null;
} else {
return valueOf(type, id.longValue(), revision);
}
}

/**
* @param <E> the generic type of the identified entity.
* @param type - see {@link #getType()}.
* @param id - see {@link #getId()}.
* @return a new instance of {@link SimpleId}.
*/
public static <E> SimpleId<E> valueOf(Class<E> type, long id) {

return valueOf(type, id, null);
}

/**
* @param <E> the generic type of the identified entity.
* @param type - see {@link #getType()}.
* @param id - see {@link #getId()}.
* @param revision - see {@link #getRevision()}.
* @return a new instance of {@link SimpleId}.
*/
public static <E> SimpleId<E> valueOf(Class<E> type, long id, Number revision) {

return new SimpleId<>(type, id, revision);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.lang.base.datatype.adapter.jpa;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

import net.sf.mmm.util.lang.base.SimpleId;

/**
* This is the implementation of {@link AttributeConverter} for {@link SimpleId}.
*
* @author Joerg Hohwiller (hohwille at users.sourceforge.net)
* @since 6.0.0
*/
@SuppressWarnings("rawtypes")
@Converter(autoApply = true)
// https://hibernate.atlassian.net/browse/HHH-8854
public class SimpleIdAttributeConverter implements AttributeConverter<SimpleId, Long> {

/**
* The constructor.
*/
public SimpleIdAttributeConverter() {

super();
}

@Override
public SimpleId convertToEntityAttribute(Long value) {

return SimpleId.valueOf(null, value);
}

@Override
public Long convertToDatabaseColumn(SimpleId datatype) {

if (datatype == null) {
return null;
}
return Long.valueOf(datatype.getId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ public interface BeanPrototypeBuilder extends AbstractBeanFactory {
*/
Bean getPrototype(String qualifiedName);

/**
* Creates a {@link BeanAccess#isVirtual() virtual} prototype that allows dynamic beans at runtime (without an
* corresponding sub-interface existing as Java code).
*
* @see BeanFactory#createPrototype(Class)
*
* @param <BEAN> the generic type of the {@link Bean}.
* @param prototype the main prototype of the {@link Bean}.
* @param dynamic the {@link BeanAccess#isDynamic() dynamic flag} of the {@link Bean}.
* @param name the explicit {@link BeanAccess#getSimpleName() name} of the {@link Bean}.
* @param superBeanPrototypes the additional prototypes of the {@link Bean}s (mixins) that will also be inherited from
* the prototype to create in addition to the given {@code prototype}. They have to be
* {@link #getPrototype(Bean) prototypes}. The prototype to create must not result in cyclic inheritance or
* inconsistent properties in case of multi-inheritance.
* @return the prototype instance of the specified {@link Bean}.
*/
<BEAN extends Bean> BEAN createPrototype(BEAN prototype, String name, Bean... superBeanPrototypes);

/**
* Creates a {@link BeanAccess#isVirtual() virtual} prototype that allows dynamic beans at runtime (without an
* corresponding sub-interface existing as Java code).
Expand All @@ -55,6 +73,10 @@ public interface BeanPrototypeBuilder extends AbstractBeanFactory {
* or inconsistent properties in case of multi-inheritance.
* @return the prototype instance of the specified {@link Bean}.
*/
<BEAN extends Bean> BEAN createPrototype(Class<BEAN> type, String name, Bean... superBeanPrototypes);
default <BEAN extends Bean> BEAN createPrototype(Class<BEAN> type, String name, Bean... superBeanPrototypes) {

BEAN superPrototypeBean = getOrCreatePrototype(type);
return createPrototype(superPrototypeBean, name, superBeanPrototypes);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.bean.api;

import net.sf.mmm.util.lang.api.Id;

/**
* This is the interface for an entity that may be loaded from or saved to a database. Typically you may want to use
* {@link EntityBean} but for legacy technologies such as JPA you have to use standard Java Beans that can directly
Expand All @@ -11,11 +13,10 @@
* <li>A {@link #getVersion() version}.</li>
* </ul>
*
* @param <ID> the generic type of the {@link #getId() primary key}.
* @author hohwille
* @since 8.0.0
*/
public interface Entity<ID> {
public interface Entity {

/** {@link net.sf.mmm.util.property.api.WritableProperty#getName() Property name} of {@link #getId() ID}. */
String PROPERTY_NAME_ID = "Id";
Expand All @@ -27,12 +28,12 @@ public interface Entity<ID> {
* @return the unique ID (primary key) of this entity or {@code null} if not available (e.g. entity is not
* persistent).
*/
ID getId();
Id<?> getId();

/**
* @param id the new {@link #getId() ID}.
*/
void setId(ID id);
void setId(Id<?> id);

/**
* @return the {@code version} of this entity. Whenever the {@link Entity} gets updated (a modification is saved and
Expand Down
Loading

0 comments on commit 490c891

Please sign in to comment.