Last active
March 19, 2016 19:21
-
-
Save mark-jay/daf667434404bfb36745 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // -------------------------------------------------------------------------------- | |
| // abstract generic stuff: | |
| public abstract class AbstractEntity { | |
| ID, hibernate-version, reflective to-string/equals/hashcode | |
| } | |
| public UIWindowFactory { | |
| public <T extends AbstractEntity> AbstractUIWindow<T> getUIWindow(T entity) {...} | |
| } | |
| public abstract class AbstractUIWindow<T extends AbstractEntity> { | |
| public com.vaddin.Window generateEditWindow(T entity) { generateDefaultReflectiveEditWindow(entity); } | |
| protected final com.vaddin.Window generateDefaultReflectiveEditWindow(T entity) { | |
| // reflective-based implementation for general case. | |
| } | |
| // the same could be done for view(read-only edit) | |
| public List<ValidationError> validate(T entity) { /* default reflective-based implementation */ } | |
| } | |
| public MigratorFactory { | |
| public <Base extends AbstractEntity, Target extends Base> Migrator<Base, Target> getMigrator(Base entity, Class<Target> targetClass) {...} | |
| } | |
| public abstract class Migrator<Base extends AbstractEntity, Target extends Base> { | |
| public abstract Target migrate(Base base); | |
| protected Target reflectiveMigrate(Base base) { /* implementation */ } | |
| } | |
| public class MainUI { | |
| public void openForm(AbstractEntity entity) { | |
| UIWindowFactory.getUIWindow(entity).show(); | |
| } | |
| public List<Class<? extends AbstractEntity>> getMigrationOptions(Class<AbstractEntity> entity) { | |
| return getAllKnownSubclasses(entity.getClass().getSuperclass()); | |
| } | |
| public Migrator<Base, Target> migrateAndOpen(Base entity, Class<Target> targetClass) { | |
| try { | |
| openForm(MigratorFactory.getMigrator(entity, targetClass).migrate(entity)); | |
| } catch (Exception e) { | |
| /* show error */ | |
| } | |
| } | |
| } | |
| // -------------------------------------------------------------------------------- | |
| // the first iteration | |
| // enitties: | |
| @Inheritance(strategy=InheritanceType.SINGLE_TABLE) | |
| @DiscriminatorColumn( | |
| name="vversion", | |
| discriminatorType=DiscriminatorType.STRING) | |
| abstract class Person extends AbstractEntity {} | |
| @DiscriminatorValue("V1") | |
| class PersonV1 extends Person { | |
| String firstName, lastName, street | |
| } | |
| // UI: | |
| public class PersonV1UIWindow extends AbstractUIWindow<PersonV1> {} // nothing specific, let's just use default reflective implementation | |
| // -------------------------------------------------------------------------------- | |
| // the second iteration | |
| @DiscriminatorValue("V2") | |
| class PersonV2 extends Person { | |
| String firstName, String patronymic, Address address | |
| } | |
| @Inheritance(strategy=InheritanceType.SINGLE_TABLE) | |
| @DiscriminatorColumn( | |
| name="vversion", | |
| discriminatorType=DiscriminatorType.STRING) | |
| abstract class Address extends AbstractEntity {} | |
| @DiscriminatorValue("V1") | |
| class AddressV1 extends Address { | |
| String street, String house; | |
| } | |
| // UI: | |
| public class PersonV2UIWindow extends AbstractUIWindow<PersonV1> {} // nothing specific, let's just use default reflective implementation | |
| // Migrator: | |
| public class PersonV2Migrator extends Migrator<Person, PersonV2> { | |
| public abstract PersonV2 migrate(Person base) { | |
| PersonV2 result = reflectiveMigrate(base); // mostly done automatically | |
| if (base instanceOf PersonV1) { | |
| result.setAddress(new Address(((PersonV1)base).getStreet(), null)); // and something is done manually | |
| } | |
| return result; | |
| } | |
| } | |
| // -------------------------------------------------------------------------------- | |
| /* | |
| -- database structure | |
| Person { int id, version, varchar vversion, firstName, lastName, street; int address_id foreign key to address } | |
| Address { int id, version, varchar vversion, street, house } | |
| -- specific constraints examples: | |
| alter table Person | |
| add check (vversion != 'V1' or street not null) | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment