org.fuchss.objectcasket.objectpacker.impl.SessionImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of object-casket Show documentation
Show all versions of object-casket Show documentation
Object Casket is a simple O/R mapper that can be used together with the Java Persistence API (JPA). The aim is to provide a simple solution for small projects to store multi-related
entities in a simple manner.
package org.fuchss.objectcasket.objectpacker.impl;
import java.io.Serializable;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.Table;
import org.fuchss.objectcasket.common.CasketError.CE1;
import org.fuchss.objectcasket.common.CasketException;
import org.fuchss.objectcasket.common.IntolerantHashMap;
import org.fuchss.objectcasket.common.IntolerantMap;
import org.fuchss.objectcasket.common.Util;
import org.fuchss.objectcasket.objectpacker.port.Session;
import org.fuchss.objectcasket.tablemodule.port.TableModule;
import org.fuchss.objectcasket.tablemodule.port.TableModuleFactory;
class SessionImpl extends SyncedSession implements Session {
protected IntolerantMap, ClassInfo>> classInfoMap = new IntolerantHashMap<>();
protected IntolerantMap, String> classTableNameMap = new IntolerantHashMap<>();
private final IntolerantMap> tableNameClassMap = new IntolerantHashMap<>();
protected IntolerantMap, JoinTableBuilder, ?>> joinTabFactoryFactoryMap = new IntolerantHashMap<>();
protected boolean check; // enables checking for reserved symbols
protected Boolean assignOnly; // true = assignOnly, false = createOnly, null = assign or create
private SessionImpl(TableModule tabMod, ConfigurationImpl config) {
super(tabMod, config);
}
static SessionImpl editDomainBuilder(TableModuleFactory modFac, ConfigurationImpl config) throws CasketException {
SessionImpl session = new SessionImpl(modFac.newTableModule(config.getConfig()), config);
session.assignOnly = true;
session.init(modFac);
session.assignOnly = null;
return session;
}
static SessionImpl mkDomainBuilder(TableModuleFactory modFac, ConfigurationImpl config) throws CasketException {
SessionImpl session = new SessionImpl(modFac.newTableModule(config.getConfig()), config);
session.assignOnly = false;
session.init(modFac);
return session;
}
static SessionImpl createSession(TableModuleFactory modFac, ConfigurationImpl config) throws CasketException {
SessionImpl session = new SessionImpl(modFac.newTableModule(config.getConfig()), config);
session.assignOnly = true;
session.init(modFac);
return session;
}
private void init(TableModuleFactory modFac) throws CasketException {
try {
this.declareClass(M2OInfo.class);
this.declareClass(M2MInfo.class);
this.check = true;
} catch (Exception exc) {
modFac.closeModule(this.tableModule);
throw CasketException.build(exc);
}
}
@Override
public synchronized void declareClass(Class>... clazz) throws CasketException {
Set> processedClasses = new HashSet<>();
Set> processedM2MInfo = new HashSet<>();
if (this.transaction != null)
throw CE1.TRANSACTION_RUNNING.defaultBuild(this.transaction);
try {
for (Class> singleClass : clazz)
this.forwardDeclareClass(singleClass, processedClasses);
for (Class> singleClass : clazz) {
ObjectBuilder> builder = new ObjectBuilder<>(this, this.tableModule, this.classInfoMap.getIfExists(singleClass));
this.objectFactoryMap.putIfNew(singleClass, builder);
for (M2MInfo, ?> info : builder.m2mFieldInfoMap.values()) {
processedM2MInfo.add(info);
this.joinTabFactoryFactoryMap.putIfNew(info, new JoinTableBuilder<>(this, this.tableModule, info));
}
}
} catch (Exception exc) {
this.undoDeclare(processedClasses, processedM2MInfo);
throw CasketException.build(exc);
}
}
private void undoDeclare(Set> processedClasses, Set> processedM2MInfo) {
for (Class> singleClass : processedClasses) {
this.classInfoMap.remove(singleClass);
String tableName = this.classTableNameMap.remove(singleClass);
this.tableNameClassMap.remove(tableName);
this.objectFactoryMap.remove(singleClass);
}
for (M2MInfo, ?> info : processedM2MInfo)
this.joinTabFactoryFactoryMap.remove(info);
}
private void forwardDeclareClass(Class> clazz, Set> processedClasses) throws CasketException {
Util.objectsNotNull(clazz);
String tableName = this.checkClassAndGetTableName(clazz);
ClassInfo> info = new ClassInfo<>(clazz, tableName);
this.classTableNameMap.put(clazz, tableName);
this.tableNameClassMap.put(tableName, clazz);
processedClasses.add(clazz);
this.classInfoMap.put(clazz, info);
}
private String checkClassAndGetTableName(Class> clazz) throws CasketException {
String tableName = this.computeTableName(clazz);
if (Boolean.TRUE.equals(this.assignOnly) && !this.tableModule.tableExists(tableName))
throw CE1.MISSING_TABLE.defaultBuild(tableName);
if (Boolean.FALSE.equals(this.assignOnly) && this.tableModule.tableExists(tableName))
throw CE1.CLASS_ALREADY_DECLARED.defaultBuild(clazz);
if (this.classInfoMap.containsKey(clazz) || this.tableNameClassMap.containsKey(tableName))
throw CE1.CLASS_ALREADY_DECLARED.defaultBuild(clazz);
return tableName;
}
private String computeTableName(Class> clazz) throws CasketException {
if (!Modifier.isFinal(clazz.getModifiers()))
throw CE1.NON_FINAL_CLASS.defaultBuild(clazz);
if (clazz.getAnnotation(jakarta.persistence.Entity.class) == null)
throw CE1.MISSING_ENTITY_ANNOTATION.defaultBuild(clazz);
Table table = clazz.getAnnotation(Table.class);
String tableName = (table != null) ? table.name() : "";
tableName = tableName.isEmpty() ? clazz.getSimpleName() : tableName;
if (this.check && tableName.contains("@"))
throw CE1.INVALID_NAME.defaultBuild(tableName);
return tableName;
}
boolean isManaged(T obj) throws CasketException {
Util.objectsNotNull(obj);
@SuppressWarnings("unchecked")
ObjectBuilder objFactory = (ObjectBuilder) this.objectFactoryMap.getIfExists(obj.getClass());
return objFactory.objectRowMap.containsKey(obj);
}
void addClient(T supplier) throws CasketException {
Util.objectsNotNull(supplier);
@SuppressWarnings("unchecked")
ObjectBuilder objFac = (ObjectBuilder) this.objectFactoryMap.getIfExists(supplier.getClass());
objFac.addClient(supplier, this.transaction);
}
void removeClient(Class clazz, Serializable pk) throws CasketException {
Util.objectsNotNull(clazz);
if (pk == null)
return;
@SuppressWarnings("unchecked")
ObjectBuilder objFac = (ObjectBuilder) this.objectFactoryMap.getIfExists(clazz);
objFac.removeClient(pk, this.transaction);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy