All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
arp.repository.Repository Maven / Gradle / Ivy
Go to download
a java development framework with aggregation, repository and process
package arp.repository;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import arp.process.CreatedProcessEntityState;
import arp.process.ProcessContext;
import arp.process.ProcessEntity;
import arp.process.ProcessEntityState;
import arp.process.TakenProcessEntityState;
import arp.process.ThreadBoundProcessContextArray;
import arp.process.TransientProcessEntityState;
import arp.util.Unsafe;
public abstract class Repository {
private static AtomicInteger ids = new AtomicInteger();
private static Repository[] repositories = new Repository[1024];
private int id;
private Function setIdFunction = null;
private Map mockStore;
protected boolean mock = false;
public static Repository getRepository(int id) {
return repositories[id];
}
protected Repository() {
id = ids.incrementAndGet();
repositories[id] = this;
}
protected void initAsMock() {
this.mock = true;
mockStore = new HashMap<>();
}
protected abstract I getId(E entity);
public E findByIdForUpdate(I id) {
ProcessContext processContext = ThreadBoundProcessContextArray
.getProcessContext();
if (!processContext.isStarted()) {
throw new RuntimeException(
"can not use repository without a process");
}
ProcessEntity processEntity = processContext
.getEntityInProcessForTake(this.id, id);
if (processEntity != null) {
ProcessEntityState entityState = processEntity.getState();
if (entityState instanceof CreatedProcessEntityState
|| entityState instanceof TakenProcessEntityState) {
return processEntity.getEntity();
} else {
return null;
}
}
E entity = doFindByIdForUpdate(id);
if (entity != null) {
processContext.takeEntityFromRepoAndPutInProcess(this.id, id,
entity);
}
return entity;
}
private E doFindByIdForUpdate(I id) {
if (!mock) {
return findByIdForUpdateFromStore(id);
} else {
return mockStore.get(id);
}
}
protected abstract E findByIdForUpdateFromStore(I id);
public E findById(I id) {
ProcessContext processContext = ThreadBoundProcessContextArray
.getProcessContext();
if (!processContext.isStarted()) {
throw new RuntimeException(
"can not use repository without a process");
}
E entity = processContext.copyEntityInProcess(this.id, id);
if (entity != null) {
return entity;
}
return doFindById(id);
}
private E doFindById(I id) {
if (!mock) {
return findByIdFromStore(id);
} else {
return mockStore.get(id);
}
}
protected abstract E findByIdFromStore(I id);
public void save(E entity) {
ProcessContext processContext = ThreadBoundProcessContextArray
.getProcessContext();
if (!processContext.isStarted()) {
throw new RuntimeException(
"can not use repository without a process");
}
I id = getId(entity);
processContext.putEntityInProcess(this.id, id, entity);
}
public E saveIfAbsent(E entity) {
ProcessContext processContext = ThreadBoundProcessContextArray
.getProcessContext();
if (!processContext.isStarted()) {
throw new RuntimeException(
"can not use repository without a process");
}
I id = getId(entity);
ProcessEntity processEntity = processContext
.putIfAbsentEntityInProcess(this.id, id, entity);
if (processEntity != null) {
ProcessEntityState entityState = processEntity.getState();
if (!(entityState instanceof TransientProcessEntityState)) {
return processEntity.getEntity();
}
}
E entityFromStore = doSaveIfAbsent(id, entity);
if (entityFromStore != null) {
processContext.takeEntityFromRepoAndPutInProcess(this.id, id,
entityFromStore);
} else {
processContext.addCreatedAggr(entity);
processContext.takeEntityFromRepoAndPutInProcess(this.id, id,
entity);
}
return entityFromStore;
}
private E doSaveIfAbsent(I id, E entity) {
if (!mock) {
return saveIfAbsentToStore(id, entity);
} else {
return mockStore.putIfAbsent(id, entity);
}
}
protected abstract E saveIfAbsentToStore(I id, E entity);
public E remove(I id) {
ProcessContext processContext = ThreadBoundProcessContextArray
.getProcessContext();
if (!processContext.isStarted()) {
throw new RuntimeException(
"can not use repository without a process");
}
ProcessEntity processEntity = processContext.removeEntityInProcess(
this.id, id);
if (processEntity != null) {
return processEntity.getEntity();
}
E entityFromStore = doFindByIdForUpdate(id);
if (entityFromStore != null) {
processContext.takeEntityFromRepoAndPutInProcessAsRemoved(this.id,
id, entityFromStore);
}
return entityFromStore;
}
public void deleteEntities(Set ids) {
if (!mock) {
removeAllToStore(ids);
} else {
for (I id : ids) {
mockStore.remove(id);
}
}
}
protected abstract void removeAllToStore(Set ids);
public void updateEntities(Map entitiesToReturn) {
if (!mock) {
updateAllToStore(entitiesToReturn);
} else {
}
}
protected abstract void updateAllToStore(Map entities);
public void createEntities(Map entitiesToCreate) {
if (!mock) {
saveAllToStore(entitiesToCreate);
} else {
mockStore.putAll(entitiesToCreate);
}
}
protected abstract void saveAllToStore(Map entities);
public void returnEntities(Set ids) {
if (!mock) {
unlockAllToStore(ids);
} else {
}
}
protected abstract void unlockAllToStore(Set ids);
public E findByIdForUpdateOrCreateAndLock(I id, E newEntity) {
E entity = findByIdForUpdate(id);
if (entity == null) {
if (setIdFunction == null) {
try {
createSetIdFunction(newEntity);
} catch (Exception e) {
}
}
setIdFunction.apply(new Object[] { newEntity, id });
E existsEntity = saveIfAbsent(newEntity);
if (existsEntity != null) {
return existsEntity;
}
return newEntity;
}
return entity;
}
private void createSetIdFunction(E newEntity) throws Exception {
Field idField = newEntity.getClass().getDeclaredField("id");
long idFieldOffset = Unsafe.getFieldOffset(idField);
Class> idFieldType = idField.getType();
if (idFieldType.equals(byte.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setByteFieldOfObject(t[0], idFieldOffset,
((Byte) t[1]).byteValue());
return null;
}
};
} else if (idFieldType.equals(short.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setShortFieldOfObject(t[0], idFieldOffset,
((Short) t[1]).shortValue());
return null;
}
};
} else if (idFieldType.equals(char.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setCharFieldOfObject(t[0], idFieldOffset,
((Character) t[1]).charValue());
return null;
}
};
} else if (idFieldType.equals(int.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setIntFieldOfObject(t[0], idFieldOffset,
((Integer) t[1]).intValue());
return null;
}
};
} else if (idFieldType.equals(float.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setFloatFieldOfObject(t[0], idFieldOffset,
((Float) t[1]).floatValue());
return null;
}
};
} else if (idFieldType.equals(long.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setLongFieldOfObject(t[0], idFieldOffset,
((Long) t[1]).longValue());
return null;
}
};
} else if (idFieldType.equals(double.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setDoubleFieldOfObject(t[0], idFieldOffset,
((Double) t[1]).doubleValue());
return null;
}
};
} else if (idFieldType.equals(boolean.class)) {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setBooleanFieldOfObject(t[0], idFieldOffset,
((Boolean) t[1]).booleanValue());
return null;
}
};
} else {
setIdFunction = new Function() {
@Override
public Object apply(Object[] t) {
Unsafe.setObjectFieldOfObject(t[0], idFieldOffset, t[1]);
return null;
}
};
}
}
}