Skip to content

Instantly share code, notes, and snippets.

@gdesatrigraha
Last active August 29, 2015 14:02
Show Gist options
  • Save gdesatrigraha/33b21b9554fc6f5c522d to your computer and use it in GitHub Desktop.
Save gdesatrigraha/33b21b9554fc6f5c522d to your computer and use it in GitHub Desktop.
JPA Enhancer Prototype
public class Order {
private long id;
private Set<Product> products;
public Order(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Set<Product> getProducts() {
if (products == null) {
products = new LinkedHashSet<>();
}
return new OneToMany1(this, products);
}
public void setProducts(Set<Product> products) {
final Set<Product> oldProducts = this.products;
this.products = products;
if (oldProducts != null) {
if (products == null) {
oldProducts.clear();
} else {
new OneToMany1(this, oldProducts).retainAll(products);
}
}
if (products != null) {
for (final Product e : products) {
if (e.getOrder() != this) {
e.setOrder(this);
}
}
}
}
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Order other = (Order) obj;
if (this.id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Order{" + "id=" + id + '}';
}
}
class Product {
private long id;
private Order order;
public Product(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Order getOrder() {
return order;
}
public void setOrder(Order newOrder) {
final Order oldOrder = this.order;
this.order = newOrder;
if (oldOrder != null) {
oldOrder.getProducts().remove(this);
}
if (newOrder != null) {
newOrder.getProducts().add(this);
}
System.out.println("product.order changed from: " + oldOrder + " to: " + newOrder);
}
@Override
public int hashCode() {
int hash = 5;
hash = 79 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Product other = (Product) obj;
if (this.id != other.id) {
return false;
}
return true;
}
@Override
public String toString() {
return "Product{" + "id=" + id + '}';
}
}
class OneToMany1 implements Set<Product> {
private final Order owner;
private final Set<Product> storage;
public OneToMany1(Order owner, Set<Product> storage) {
this.owner = owner;
this.storage = storage;
}
@Override
public Iterator<Product> iterator() {
return storage.iterator();
}
@Override
public int size() {
return storage.size();
}
@Override
public boolean isEmpty() {
return storage.isEmpty();
}
@Override
public boolean contains(Object o) {
return storage.contains(o);
}
@Override
public boolean add(Product e) {
final boolean ret = storage.add(e);
if (e.getOrder() == owner) {
return ret;
} else if (e.getOrder() == null) {
e.setOrder(owner);
return ret;
} else {
e.getOrder().getProducts().remove(e);
return ret;
}
}
@Override
public boolean remove(Object o) {
final Product e = (Product) o;
final boolean ret = storage.remove(e);
if (e.getOrder() == owner) {
e.setOrder(null);
}
return ret;
}
@Override
public void clear() {
final List<Product> oldEntries = new ArrayList<>(storage);
storage.clear();
for (final Product e : oldEntries) {
if (e.getOrder() == owner) {
e.setOrder(null);
}
}
}
@Override
public boolean equals(Object o) {
return storage.equals(o);
}
@Override
public int hashCode() {
return storage.hashCode();
}
@Override
public boolean removeAll(Collection<?> c) {
boolean ret = false;
for (final Object e : c) {
if (remove((Product) e)) {
ret = true;
}
}
return ret;
}
@Override
public Object[] toArray() {
return storage.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return storage.toArray(a);
}
@Override
public boolean containsAll(Collection<?> c) {
return storage.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends Product> c) {
return storage.addAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
boolean ret = false;
final LinkedHashSet<Product> removed = new LinkedHashSet<>(c.size());
for (final Product e : storage) {
if (!c.contains(e)) {
removed.add(e);
}
}
for (final Product e : removed) {
if (remove(e)) {
ret = true;
}
}
return ret;
}
@Override
public String toString() {
return storage.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment