Commit c2a29129 authored by Mamadou Saliou DIALLO's avatar Mamadou Saliou DIALLO

create generic association handler

parent 5a904ddf
......@@ -22,7 +22,16 @@
<artifactId>not-alone-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
......
package fr.univnantes.alma.references.abstracts;
import fr.univnantes.alma.references.interfaces.ManyToManyAssociation;
import org.apache.commons.lang3.Validate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public abstract class AbstractManyToManyAssociation<CONTAINER, TARGET> implements ManyToManyAssociation<CONTAINER,TARGET> {
protected final CONTAINER container;
private final Collection<TARGET> references = new ArrayList<>();
/**
* Crée une nouvelle association bidirectionnelle
* @param container conteneur de l'assocation
*/
public AbstractManyToManyAssociation(CONTAINER container) {
Validate.notNull(container);
this.container = container;
}
/**
* Appends the specified element to the end of this list.
*
* @param reference element to be appended to this
* @return <tt>true</tt> if this collection changed as a result of the call.
*/
@Override
public boolean add(TARGET reference) {
Validate.notNull(reference);
opposite(reference).basicAdd(container);
return this.basicAdd(reference);
}
/**
* Make simple add operation on the collection
* @param reference element to be append to this
* @return
*/
public boolean basicAdd(TARGET reference) {
return this.references.add(reference);
}
/**
* Adds all of the elements in the specified collection to this collection.
*
* @param references collection containing elements to be added to this
* collection.
* @return <tt>true</tt> if this collection changed as a result of the call.
*/
@Override
public boolean addAll(Collection<TARGET> references) {
boolean result = true;
for(TARGET value : references){
result = result && this.add(value);
}
return result;
}
/**
* Removes the first occurrence of the specified element from this list, if
* it is present.
*
* @param reference element to be removed from this list, if present.
* @return <tt>true</tt> if an element was removed as a result of this call
*/
@Override
public boolean remove(TARGET reference) {
Validate.notNull(reference);
if(references.contains(reference)){
opposite(reference).basicRemove(container);
return this.basicRemove(reference);
}
return false;
}
/**
* Removes the first occurrence of the specified element from this list, if
* it is present.
*
* @param reference element to be removed from this list, if present.
* @return <tt>true</tt> if an element was removed as a result of this call
*/
public boolean basicRemove(TARGET reference) {
return this.references.remove(reference);
}
/**
* Removes all of this collection's elements that are also contained in the
* specified collection
*
* @param references collection containing elements to be removed from this collection
* @return <tt>true</tt> if an element was removed as a result of this call.
*/
@Override
public boolean removeAll(Collection<TARGET> references) {
boolean result = true;
for(TARGET value : references){
result = result && remove(value);
}
return result;
}
/**
* Returns <tt>true</tt> if this collection contains the specified element.
*
* @param reference element whose presence in this collection is to be tested
* @return <tt>true</tt> if this collection contains the specified element
*/
@Override
public boolean contains(TARGET reference) {
return references.contains(reference);
}
/**
* Returns <tt>true</tt> if this collection contains all of the elements
* in the specified collection.
*
* @param references collection to be checked for containment in this collection
* @return <tt>true</tt> if this collection contains all of the elements
* in the specified collection.
*/
@Override
public boolean containsAll(Collection<TARGET> references) {
return references.containsAll(references);
}
/**
* Returns an object array containing all of the elements in this collection.
*
* @return an object array containing all of the elements in this collection.
*/
@Override
public Object[] toArray() {
return references.toArray();
}
/**
* Returns an array containing all of the elements in this collection.
*
* @param a
* @return an array containing all of the elements in this collection.
*/
@Override
public TARGET[] toArray(TARGET[] a) {
return references.toArray(a);
}
/**
* Removes all of the elements from this collection.
* If minItem is defined, it will not removed
*/
@Override
public void clear() {
for(TARGET value: references){
this.remove(value);
}
}
/**
* Returns <tt>true</tt> if this collection contains no elements.
*
* @return <tt>true</tt> if this collection contains no elements.
*/
@Override
public boolean isEmpty() {
return references.isEmpty();
}
/**
* Returns the number of elements in this collection.
*
* @return the number of elements in this collection.
*/
@Override
public int size() {
return references.size();
}
/**
* Returns an iterator over the elements in this collection.
*
* @return an <tt>Iterator</tt> over the elements in this collection.
*/
@Override
public Iterator<TARGET> iterator() {
return references.iterator();
}
}
package fr.univnantes.alma.references.abstracts;
import fr.univnantes.alma.references.interfaces.ManyToOneAssociation;
import fr.univnantes.alma.references.interfaces.OneToManyAssociation;
import java.util.Objects;
public abstract class AbstractManyToOneAssociation<CONTAINER, TARGET> implements ManyToOneAssociation<CONTAINER, TARGET> {
protected CONTAINER container;
private TARGET value;
public AbstractManyToOneAssociation(CONTAINER container) {
this.container = container;
}
/**
* Define handshake with other reference
*
* @param value value to set
*/
@Override
public void set(TARGET value) {
if (this.isSet()) {
oppositeReferenceFor(this.value).basicRemove(container);
}
this.basicSet(value);
OneToManyAssociation<TARGET,CONTAINER> opposite = oppositeReferenceFor(value);
opposite.basicAdd(container);
}
/**
* Return container value
*
* @return
*/
@Override
public TARGET get() {
return value;
}
/**
* Define une nouvelle reference
*
* @param reference
*/
@Override
public void basicSet(TARGET reference) {
Objects.requireNonNull(reference);
this.value = reference;
}
/**
* Détruit basiquement une reference
*/
@Override
public void basicUnset() {
value = null;
}
/**
* Reference opposé
*
* @param value
* @return
*/
@Override
public abstract OneToManyAssociation<TARGET, CONTAINER> oppositeReferenceFor(TARGET value);
/**
* Return true if reference is defined
*
* @return
*/
@Override
public boolean isSet() {
return value != null;
}
/**
* Destroy defined reference
*/
@Override
public void unset() {
if (this.isSet()) {
OneToManyAssociation<TARGET, CONTAINER> opposite = oppositeReferenceFor(value);
opposite.basicRemove(container);
}
this.basicUnset();
}
}
package fr.univnantes.alma.references.abstracts;
import fr.univnantes.alma.references.interfaces.Reference;
import fr.univnantes.alma.references.interfaces.ManyToOneAssociation;
import fr.univnantes.alma.references.interfaces.OneToManyAssociation;
import org.apache.commons.lang3.Validate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public abstract class AbstractOneToManyAssociation<CONTAINER, TARGET>
implements OneToManyAssociation<CONTAINER, TARGET>, Reference {
protected CONTAINER container;
private Collection<TARGET> values = new ArrayList<TARGET>();
public AbstractOneToManyAssociation(CONTAINER container) {
this.container = container;
}
/**
* Ajoute une reference dans la collection
*
* @param reference
*/
@Override
public boolean basicAdd(TARGET reference) {
return this.values.add(reference);
}
/**
* Supprime basiquement une reference
*
* @param reference
*/
@Override
public boolean basicRemove(TARGET reference) {
return this.values.remove(reference);
}
/**
* Reference opposée
*
* @param value valeur dont on cherche la reference
* @return
*/
@Override
public abstract ManyToOneAssociation<TARGET, CONTAINER> oppositeReferenceFor(TARGET value);
/**
* Return true if reference is defined
*
* @return
*/
@Override
public boolean isSet() {
return values.isEmpty();
}
/**
* Destroy defined reference
*/
@Override
public void unset() {
}
/**
* Appends the specified element to the end of this list.
*
* @param reference element to be appended to this
* @return <tt>true</tt> if this collection changed as a result of the call.
*/
@Override
public boolean add(TARGET reference) {
ManyToOneAssociation<TARGET, CONTAINER> opposite = this.oppositeReferenceFor(reference);
opposite.unset();
opposite.basicSet(container);
return this.basicAdd(reference);
}
/**
* Adds all of the elements in the specified collection to this collection.
*
* @param references collection containing elements to be added to this
* collection.
* @return <tt>true</tt> if this collection changed as a result of the call.
*/
@Override
public boolean addAll(Collection<TARGET> references) {
Validate.notNull(references);
Validate.notEmpty(references);
boolean result = true;
for(TARGET value: references){
result = result && add(value);
}
return result;
}
/**
* Removes the first occurrence of the specified element from this list, if
* it is present.
*
* @param reference element to be removed from this list, if present.
* @return <tt>true</tt> if an element was removed as a result of this call
*/
@Override
public boolean remove(TARGET reference) {
if(this.values.contains(reference)){
oppositeReferenceFor(reference).basicUnset();
return this.basicRemove(reference);
}
return false;
}
/**
* Removes all of this collection's elements that are also contained in the
* specified collection
*
* @param references collection containing elements to be removed from this collection
* @return <tt>true</tt> if an element was removed as a result of this call.
*/
@Override
public boolean removeAll(Collection<TARGET> references) {
Validate.notNull(references);
Validate.notEmpty(references);
boolean result = true;
for(TARGET value: references){
result = result && remove(value);
}
return result;
}
/**
* Returns <tt>true</tt> if this collection contains the specified element.
*
* @param reference element whose presence in this collection is to be tested
* @return <tt>true</tt> if this collection contains the specified element
*/
@Override
public boolean contains(TARGET reference) {
return values.contains(reference);
}
/**
* Returns <tt>true</tt> if this collection contains all of the elements
* in the specified collection.
*
* @param references collection to be checked for containment in this collection
* @return <tt>true</tt> if this collection contains all of the elements
* in the specified collection.
*/
@Override
public boolean containsAll(Collection<TARGET> references) {
Validate.notNull(references);
Validate.notEmpty(references);
return values.containsAll(references);
}
/**
* Returns an object array containing all of the elements in this collection.
*
* @return an object array containing all of the elements in this collection.
*/
@Override
public Object[] toArray() {
return values.toArray();
}
/**
* Returns an array containing all of the elements in this collection.
*
* @param a
* @return an array containing all of the elements in this collection.
*/
@Override
public TARGET[] toArray(TARGET[] a) {
return values.toArray(a);
}
/**
* Removes all of the elements from this collection.
*/
@Override
public void clear() {
removeAll(values);
}
/**
* Returns <tt>true</tt> if this collection contains no elements.
*
* @return <tt>true</tt> if this collection contains no elements.
*/
@Override
public boolean isEmpty() {
return values.isEmpty();
}
/**
* Returns the number of elements in this collection.
*
* @return the number of elements in this collection.
*/
@Override
public int size(){
return values.size();
}
/**
* Returns an iterator over the elements in this collection.
*
* @return an <tt>Iterator</tt> over the elements in this collection.
*/
@Override
public Iterator<TARGET> iterator() {
return values.iterator();
}
}
package fr.univnantes.alma.references.abstracts;
import fr.univnantes.alma.references.interfaces.OneToOneAssociation;
import org.apache.commons.lang3.Validate;
import java.util.function.Function;
public abstract class AbstractOneToOneAssociation<CONTAINER, TARGET> implements OneToOneAssociation<CONTAINER, TARGET> {
private final CONTAINER container;
private TARGET target;
private Function<OneToOneAssociation<TARGET,CONTAINER>, TARGET > oppositeFunction;
public AbstractOneToOneAssociation(CONTAINER container) {
this.container = container;
}
@Override
public void basicSet(TARGET newTarget) {
Validate.notNull(newTarget);
this.target = newTarget;
}
@Override
public void basicUnset() {
this.target = null;
}
@Override
public void set(TARGET newTarget) {
Validate.notNull(newTarget);
if (isSet()) {
this.unset();
}
if (this.oppositeReferenceFor(newTarget).isSet()) {
this.oppositeReferenceFor(newTarget).unset();
}
this.basicSet(newTarget);
this.oppositeReferenceFor(newTarget).basicSet(container);
}
@Override
public TARGET get() {
return target;
}
@Override
public boolean isSet() {
return target != null;
}
@Override
public void unset() {
if (!isSet()) return;
this.oppositeReferenceFor(target).basicUnset();
this.basicUnset();
}
}