In the core module the Annotation Processor is defined and it’s where the magic happens. The magic behind this is separated into two steps:
The data is collected by the three classes in the at.rseiler.spbee.core.collector package.
Collects the data of the annotated @Dto interfaces and classes.
Collects the data of the annotated @Entity classes.
The code is generated by the three classes in the at.rseiler.spbee.core.generator package. The generators uses the Codemodel library to build the Java source code.
Generates the code for the DTO classes. All collected non spBee annotations will be put on the corresponding methods.
The DTO methods have 5 flavors:
public List<Entity> getUsers() { Object interceptorIdObject = SpInterceptor.before("sp_get_user"); // optional List<Entity> list = ((List<Entity>) sp.execute().get("#result-set-0")); SpInterceptor.after(interceptorIdObject, "sp_get_user"); // optional return list; }
public Entity getEntity(int id) { Object interceptorIdObject = SpInterceptor.before("sp_get_user"); // optional List<Entity> list = ((List<Entity>) spGetUser.execute(id).get("#result-set-0")); SpInterceptor.after(interceptorIdObject, "sp_get_user"); // optional if (list.size() == 1) { return list.get(0); } else { if (list.size() == 0) { throw new ObjectDoesNotExist(); } else { throw new MultipleObjectsReturned(); } } }
public Optional<Entity> getOptionalEntity(int id) { Object interceptorIdObject = SpInterceptor.before("sp_get_user"); // optional List<Entity> list = ((List<Entity> ) spGetUser.execute(id).get("#result-set-0")); SpInterceptor.after(interceptorIdObject, "sp_get_user"); // optional if (list.size() == 1) { return Optional.of(list.get(0)); } else { if (list.size() == 0) { return Optional.empty(); } else { throw new MultipleObjectsReturned(); } } }
public Entity getEntityOrNull(int id) { Object interceptorIdObject = SpInterceptor.before("sp_get_user"); // optional List<Entity> list = ((List<Entity>) spGetUser.execute(id).get("#result-set-0")); SpInterceptor.after(interceptorIdObject, "sp_get_user"); // optional if (list.size() == 1) { return list.get(0); } else { if (list.size() == 0) { return null; } else { throw new MultipleObjectsReturned(); } } }
public UserPermissionsResultSet getUserWithPermissions(int id) { Object interceptorIdObject = SpInterceptor.before("sp_get_user"); // optional Map<String, Object> map = spGetUserWithPermissions.execute(id); SpInterceptor.after(interceptorIdObject, "sp_get_user"); // optional List<Entity> list0 = ((List<Entity> ) map.get("#result-set-0")); Optional obj0; if (list0.size() == 1) { obj0 = Optional.of(list0.get(0)); } else { if (list0.size() == 0) { obj0 = Optional.empty(); } else { throw new MultipleObjectsReturned(); } } List<Permission> list1 = ((List<Permission>) map.get("#result-set-1")); return new UserPermissionsResultSet(obj0, list1); }
Generates the code for the MapperClasses. The Entity’s constructor must only have basic parameters. It’s not possible to use other entities in the constructor. If a more complex mapping is required then write an own MapperClass and use the @RowMapper annotation.
public class EntityMapper implements RowMapper<Entity> { public Entity mapRow(ResultSet rs, int rowNum) throws SQLException { return new Entity(rs.*(1), rs.*(2)); } }
Generates the code for the StoredProcedure classes.
public class SpGetEntity extends StoredProcedure { public SpGetEntity(DataSource dataSource) { super(dataSource, "sp_get_entity"); declareParameter(new SqlParameter("id", Types.INTEGER)); declareParameter(new SqlReturnResultSet("#result-set-0", new EntityDefaultMapper())); compile(); } public Map<String, Object> execute(int id) { return super.execute(id); } }
public class SpGetEntity extends StoredProcedure { public SpGetEntity(DataSource dataSource) { super(dataSource, "sp_get_entity"); declareParameter(new SqlParameter("id", Types.INTEGER)); declareParameter(new SqlReturnResultSet("#result-set-0", new Entity1DefaultMapper())); declareParameter(new SqlReturnResultSet("#result-set-1", new Entity2DefaultMapper())); compile(); } public Map<String, Object> execute(int id) { return super.execute(id); } }