Skip to content

Commit

Permalink
First step in refactor of manager
Browse files Browse the repository at this point in the history
  • Loading branch information
minborg committed Oct 1, 2016
1 parent 9977a0c commit e11468a
Show file tree
Hide file tree
Showing 19 changed files with 416 additions and 165 deletions.
Expand Up @@ -61,6 +61,7 @@
import com.speedment.runtime.config.util.DocumentDbUtil; import com.speedment.runtime.config.util.DocumentDbUtil;
import static com.speedment.runtime.config.util.DocumentUtil.Name.DATABASE_NAME; import static com.speedment.runtime.config.util.DocumentUtil.Name.DATABASE_NAME;
import com.speedment.runtime.config.identifier.ColumnIdentifier; import com.speedment.runtime.config.identifier.ColumnIdentifier;
import com.speedment.runtime.config.identifier.TableIdentifier;
import static com.speedment.runtime.config.util.DocumentUtil.relativeName; import static com.speedment.runtime.config.util.DocumentUtil.relativeName;


/** /**
Expand All @@ -69,9 +70,9 @@
* @author Per-Åke Minborg * @author Per-Åke Minborg
*/ */
public final class GeneratedEntityTranslator extends AbstractEntityAndManagerTranslator<Interface> { public final class GeneratedEntityTranslator extends AbstractEntityAndManagerTranslator<Interface> {

public final static String IDENTIFIER_NAME = "Identifier"; public final static String IDENTIFIER_NAME = "Identifier";

private @Inject Injector injector; private @Inject Injector injector;
private @Inject TypeMapperComponent typeMappers; private @Inject TypeMapperComponent typeMappers;


Expand All @@ -82,12 +83,16 @@ public GeneratedEntityTranslator(Table table) {
@Override @Override
protected Interface makeCodeGenModel(File file) { protected Interface makeCodeGenModel(File file) {


final Type tableIdentifierType = SimpleParameterizedType.create(TableIdentifier.class, getSupport().entityType());

final Enum identifierEnum = Enum.of(IDENTIFIER_NAME) final Enum identifierEnum = Enum.of(IDENTIFIER_NAME)
.add(Field.of("columnName", String.class).private_().final_()) .add(Field.of("columnName", String.class).private_().final_())
.add(Field.of("tableIdentifier", tableIdentifierType).private_().final_())
.add(SimpleParameterizedType.create(ColumnIdentifier.class, getSupport().entityType())) .add(SimpleParameterizedType.create(ColumnIdentifier.class, getSupport().entityType()))
.add(Constructor.of() .add(Constructor.of()
.add(Field.of("columnName", String.class)) .add(Field.of("columnName", String.class))
.add("this.columnName = columnName;") .add("this.columnName = columnName;")
.add("this.tableIdentifier = TableIdentifier.of(getDbmsName(), getSchemaName(), getTableName());")
) )
.add(Method.of("getDbmsName", String.class).public_() .add(Method.of("getDbmsName", String.class).public_()
.add(OVERRIDE) .add(OVERRIDE)
Expand All @@ -104,14 +109,17 @@ protected Interface makeCodeGenModel(File file) {
.add(Method.of("getColumnName", String.class).public_() .add(Method.of("getColumnName", String.class).public_()
.add(OVERRIDE) .add(OVERRIDE)
.add("return this.columnName;") .add("return this.columnName;")
)
.add(Method.of("asTableIdentifier", tableIdentifierType).public_()
.add(OVERRIDE)
.add("return this.tableIdentifier;")
); );


return newBuilder(file, getSupport().generatedEntityName()) return newBuilder(file, getSupport().generatedEntityName())
/** /**
* General * General
*/ */
.forEveryTable((intrf, col) -> intrf.public_().add(identifierEnum)) .forEveryTable((intrf, col) -> intrf.public_().add(identifierEnum))

/** /**
* Getters * Getters
*/ */
Expand All @@ -132,7 +140,6 @@ protected Interface makeCodeGenModel(File file) {
) )
); );
}) })

/** /**
* Setters * Setters
*/ */
Expand All @@ -150,7 +157,6 @@ protected Interface makeCodeGenModel(File file) {
.add(RETURN.setText("this " + getSupport().entityName() + " instance"))) .add(RETURN.setText("this " + getSupport().entityName() + " instance")))
); );
}) })

/** /**
* Finders * Finders
*/ */
Expand All @@ -164,16 +170,16 @@ protected Interface makeCodeGenModel(File file) {
file.add(Import.of(fuSupport.entityType())); file.add(Import.of(fuSupport.entityType()));


intrf.add(Method.of(FINDER_METHOD_PREFIX + getSupport().typeName(col), intrf.add(Method.of(FINDER_METHOD_PREFIX + getSupport().typeName(col),
col.isNullable() col.isNullable()
? DefaultType.optional(fuSupport.entityType()) ? DefaultType.optional(fuSupport.entityType())
: fuSupport.entityType() : fuSupport.entityType()
) )
.set(Javadoc.of( .set(Javadoc.of(
"Queries the specified manager for the referenced " + "Queries the specified manager for the referenced "
fuSupport.entityName() + ". If no such " + + fuSupport.entityName() + ". If no such "
fuSupport.entityName() + + fuSupport.entityName()
" exists, an {@code NullPointerException} will be thrown." + " exists, an {@code NullPointerException} will be thrown."
).add(DefaultJavadocTag.PARAM.setValue("foreignManager").setText("the manager to query for the entity")) ).add(DefaultJavadocTag.PARAM.setValue("foreignManager").setText("the manager to query for the entity"))
.add(DefaultJavadocTag.RETURN.setText("the foreign entity referenced")) .add(DefaultJavadocTag.RETURN.setText("the foreign entity referenced"))
) )
.add(Field.of("foreignManager", SimpleParameterizedType.create( .add(Field.of("foreignManager", SimpleParameterizedType.create(
Expand All @@ -182,18 +188,17 @@ protected Interface makeCodeGenModel(File file) {
); );
}); });
}) })

/** /**
* Fields * Fields
*/ */
.forEveryColumn((intrf, col) -> { .forEveryColumn((intrf, col) -> {


final EntityTranslatorSupport.ReferenceFieldType ref = final EntityTranslatorSupport.ReferenceFieldType ref
EntityTranslatorSupport.getReferenceFieldType( = EntityTranslatorSupport.getReferenceFieldType(
file, getSupport().tableOrThrow(), col, getSupport().entityType(), injector file, getSupport().tableOrThrow(), col, getSupport().entityType(), injector
); );


final Type entityType = getSupport().entityType(); final Type entityType = getSupport().entityType();
final String shortEntityName = getSupport().entityName(); final String shortEntityName = getSupport().entityName();


file.add(Import.of(entityType)); file.add(Import.of(entityType));
Expand All @@ -210,9 +215,9 @@ file, getSupport().tableOrThrow(), col, getSupport().entityType(), injector
.map(fkc -> { .map(fkc -> {
final FkHolder fu = new FkHolder(injector, fkc.getParentOrThrow()); final FkHolder fu = new FkHolder(injector, fkc.getParentOrThrow());
final TranslatorSupport<Table> fuSupport = fu.getForeignEmt().getSupport(); final TranslatorSupport<Table> fuSupport = fu.getForeignEmt().getSupport();

return ", " + fuSupport.entityName() + "." + return ", " + fuSupport.entityName() + "."
fuSupport.namer().javaStaticFieldName( + fuSupport.namer().javaStaticFieldName(
fu.getForeignColumn().getJavaName() fu.getForeignColumn().getJavaName()
); );
}).orElse(""); }).orElse("");
Expand Down Expand Up @@ -265,10 +270,10 @@ file, getSupport().tableOrThrow(), col, getSupport().entityType(), injector


@Override @Override
protected String getJavadocRepresentText() { protected String getJavadocRepresentText() {
return "The generated base for the {@link " + return "The generated base for the {@link "
getSupport().entityType().getTypeName() + + getSupport().entityType().getTypeName()
"}-interface representing entities of the {@code " + + "}-interface representing entities of the {@code "
getDocument().getName() + "}-table in the database."; + getDocument().getName() + "}-table in the database.";
} }


@Override @Override
Expand Down Expand Up @@ -296,7 +301,7 @@ static Type getterReturnType(TypeMapperComponent typeMappers, Column col) {
retType = OptionalBoolean.class; retType = OptionalBoolean.class;
} else { } else {
retType = SimpleParameterizedType.create(Optional.class, type); retType = SimpleParameterizedType.create(Optional.class, type);
} }
} else { } else {
retType = type; retType = type;
} }
Expand Down
Expand Up @@ -46,4 +46,10 @@ public interface ColumnIdentifier<ENTITY> extends
HasDbmsName, HasDbmsName,
HasSchemaName, HasSchemaName,
HasTableName, HasTableName,
HasColumnName {} HasColumnName {

default TableIdentifier<ENTITY> asTableIdentifier() {
return TableIdentifier.of(getDbmsName(), getSchemaName(), getTableName());
}

}
Expand Up @@ -21,6 +21,9 @@
import com.speedment.runtime.config.identifier.trait.HasTableName; import com.speedment.runtime.config.identifier.trait.HasTableName;
import com.speedment.runtime.config.internal.identifier.TableIdentifierImpl; import com.speedment.runtime.config.internal.identifier.TableIdentifierImpl;
import com.speedment.runtime.config.util.DocumentDbUtil; import com.speedment.runtime.config.util.DocumentDbUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;


/** /**
* Identifies a particular Table. The identifier is an immutable non-complex * Identifies a particular Table. The identifier is an immutable non-complex
Expand All @@ -30,7 +33,7 @@
* To find the actual documents referred to by the identifier, the following * To find the actual documents referred to by the identifier, the following
* utility methods can be used: * utility methods can be used:
* <ul> * <ul>
*
* <li>DocumentDbUtil#referencedTable(Project, Project, TableIdentifier) * <li>DocumentDbUtil#referencedTable(Project, Project, TableIdentifier)
* <li>DocumentDbUtil#referencedSchema(Project, Project, TableIdentifier) * <li>DocumentDbUtil#referencedSchema(Project, Project, TableIdentifier)
* <li>DocumentDbUtil#referencedDbms(Project, TableIdentifier) * <li>DocumentDbUtil#referencedDbms(Project, TableIdentifier)
Expand All @@ -47,8 +50,16 @@ public interface TableIdentifier<ENTITY> extends
HasSchemaName, HasSchemaName,
HasTableName { HasTableName {


static class Hidden {

private static final Map<TableIdentifier, TableIdentifier> INTERNED = new ConcurrentHashMap<>();

}

static <ENTITY> TableIdentifier<ENTITY> of(String dbmsName, String schemaName, String tableName) { static <ENTITY> TableIdentifier<ENTITY> of(String dbmsName, String schemaName, String tableName) {
return new TableIdentifierImpl<>(dbmsName, schemaName, tableName); final TableIdentifier<ENTITY> newTableIdentity = new TableIdentifierImpl<>(dbmsName, schemaName, tableName);
Hidden.INTERNED.putIfAbsent(newTableIdentity, newTableIdentity);
return Hidden.INTERNED.get(newTableIdentity);
} }


} }
Expand Up @@ -66,28 +66,28 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass()) { if (getClass() != obj.getClass()) {
return false; return false;
} }
if (this.hashCode != obj.hashCode()) { if (hashCode != obj.hashCode()) {
return false; return false;
} }
final TableIdentifierImpl<?> other = (TableIdentifierImpl<?>) obj; final TableIdentifierImpl<?> other = (TableIdentifierImpl<?>) obj;


if (!Objects.equals(this.dbmsName, other.dbmsName)) { if (!Objects.equals(dbmsName, other.dbmsName)) {
return false; return false;
} }
if (!Objects.equals(this.schemaName, other.schemaName)) { if (!Objects.equals(schemaName, other.schemaName)) {
return false; return false;
} }
if (!Objects.equals(this.tableName, other.tableName)) { if (!Objects.equals(tableName, other.tableName)) {
return false; return false;
} }
return true; return true;
} }


private int privateHashCode() { private int privateHashCode() {
int hash = 5; int hash = 5;
hash = 53 * hash + Objects.hashCode(this.dbmsName); hash = 53 * hash + Objects.hashCode(dbmsName);
hash = 53 * hash + Objects.hashCode(this.schemaName); hash = 53 * hash + Objects.hashCode(schemaName);
hash = 53 * hash + Objects.hashCode(this.tableName); hash = 53 * hash + Objects.hashCode(tableName);
return hash; return hash;
} }


Expand Down
@@ -0,0 +1,32 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.speedment.runtime.config.identifier;

import org.junit.Test;
import static org.junit.Assert.*;

/**
*
* @author Per Minborg
*/
public class TableIdentifierTest {

@Test
public void testOf() {
final String db = "db";
final String sc = "sc";
final String ta = "ta";

TableIdentifier<Integer> ti0 = TableIdentifier.of(db, sc, ta);
TableIdentifier<Integer> ti1 = TableIdentifier.of(db, sc, ta);
TableIdentifier<Integer> ti2 = TableIdentifier.of(db, sc, "Arne");

assertTrue(ti0 == ti1); // Make sure that the interface interns duplicates
assertFalse(ti0 == ti2);

}

}
@@ -0,0 +1,24 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.speedment.runtime.core.component;

import java.sql.ResultSet;

/**
*
* @author Per Minborg
*/
public interface SqlStreamSupplierComponent extends StreamSupplierComponent {

public interface Support<ENTITY> {

String getSql();

ENTITY from(ResultSet rs);

}

}
Expand Up @@ -17,6 +17,7 @@
package com.speedment.runtime.core.component; package com.speedment.runtime.core.component;


import com.speedment.common.injector.annotation.InjectKey; import com.speedment.common.injector.annotation.InjectKey;
import com.speedment.runtime.config.identifier.TableIdentifier;
import com.speedment.runtime.core.field.trait.HasComparableOperators; import com.speedment.runtime.core.field.trait.HasComparableOperators;
import com.speedment.runtime.core.stream.StreamDecorator; import com.speedment.runtime.core.stream.StreamDecorator;


Expand All @@ -32,48 +33,35 @@
@InjectKey(StreamSupplierComponent.class) @InjectKey(StreamSupplierComponent.class)
public interface StreamSupplierComponent { public interface StreamSupplierComponent {


/**
* Does all the preparations required to start serving streams
* before returning. The component must never be called before
* this method has returned.
*/
void start();

/**
* Stops the component, releasing any resources. When this method
* returns, the component must never be called again.
*/
void stop();

/** /**
* Basic stream over all entities. * Basic stream over all entities.
* *
* @param <ENTITY> entity type * @param <ENTITY> entity type
* @param entityClass the entity class * @param tableIdentifier the identifier to use
* @param decorator decorates the stream before building it * @param decorator decorates the stream before building it
* @return a stream for the given entity class * @return a stream for the given entity class
*/ */
<ENTITY> Stream<ENTITY> stream(Class<ENTITY> entityClass, StreamDecorator decorator); <ENTITY> Stream<ENTITY> stream(TableIdentifier<ENTITY> tableIdentifier, StreamDecorator decorator);


/** /**
* Finds a particular entity in the source where the specified field has * Finds a particular entity in the source where the specified field has
* the specified value. This is a form of key-value lookup than can * the specified value. This is a form of key-value lookup than can
* potentially be more efficient with for an example foreign key references. * potentially be more efficient with for an example foreign key references.
* *
* @param <ENTITY> the entity type * @param <ENTITY> the entity type
* @param <V> the java type of the column * @param <V> the java type of the column
* @param entityClass the entity interface .class * @param tableIdentifier the identifier to use
* @param field the field to select on * @param field the field to select on
* @param value the value of that field for the entity to return * @param value the value of that field for the entity to return
* @return entity found or empty if none existed with that value * @return entity found or empty if none existed with that value
*/ */
default <ENTITY, V extends Comparable<? super V>> default <ENTITY, V extends Comparable<? super V>>
Optional<ENTITY> findAny( Optional<ENTITY> findAny(
Class<ENTITY> entityClass, TableIdentifier<ENTITY> tableIdentifier,
HasComparableOperators<ENTITY, V> field, HasComparableOperators<ENTITY, V> field,
V value) { V value) {


return stream(entityClass, StreamDecorator.IDENTITY) return stream(tableIdentifier, StreamDecorator.identity())
.filter(field.equal(value)) .filter(field.equal(value))
.findAny(); .findAny();
} }
Expand Down
Expand Up @@ -27,7 +27,7 @@
import com.speedment.runtime.core.internal.component.EntityManagerImpl; import com.speedment.runtime.core.internal.component.EntityManagerImpl;
import com.speedment.runtime.core.internal.component.InfoComponentImpl; import com.speedment.runtime.core.internal.component.InfoComponentImpl;
import com.speedment.runtime.core.internal.component.ManagerComponentImpl; import com.speedment.runtime.core.internal.component.ManagerComponentImpl;
import com.speedment.runtime.core.internal.component.NativeStreamSupplierComponentImpl; import com.speedment.runtime.core.internal.component.SqlStreamSupplierComponentImpl;
import com.speedment.runtime.core.internal.component.PasswordComponentImpl; import com.speedment.runtime.core.internal.component.PasswordComponentImpl;
import com.speedment.runtime.core.internal.component.PrimaryKeyFactoryComponentImpl; import com.speedment.runtime.core.internal.component.PrimaryKeyFactoryComponentImpl;
import com.speedment.runtime.core.internal.component.ProjectComponentImpl; import com.speedment.runtime.core.internal.component.ProjectComponentImpl;
Expand All @@ -47,13 +47,12 @@
public abstract class AbstractSpeedment implements Speedment { public abstract class AbstractSpeedment implements Speedment {


public static InjectBundle include() { public static InjectBundle include() {
return InjectBundle.of( return InjectBundle.of(InfoComponentImpl.class,
InfoComponentImpl.class,
ConnectionPoolComponentImpl.class, ConnectionPoolComponentImpl.class,
DbmsHandlerComponentImpl.class, DbmsHandlerComponentImpl.class,
EntityManagerImpl.class, EntityManagerImpl.class,
ManagerComponentImpl.class, ManagerComponentImpl.class,
NativeStreamSupplierComponentImpl.class, SqlStreamSupplierComponentImpl.class,
PasswordComponentImpl.class, PasswordComponentImpl.class,
PrimaryKeyFactoryComponentImpl.class, PrimaryKeyFactoryComponentImpl.class,
ProjectComponentImpl.class, ProjectComponentImpl.class,
Expand Down

0 comments on commit e11468a

Please sign in to comment.