package org.aplikator.server.descriptor; import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.aplikator.server.data.BinaryData; import org.aplikator.server.data.PersisterTriggers; import org.aplikator.server.persistence.PersisterFactory; public abstract class Entity extends LocalizedServerDescriptorBase implements Cloneable { public static final String TIMESTAMP_NAME = "UPDATE_TIMESTAMP"; private Property<Integer> primaryKey; // index configuration properties private boolean indexed = false; private int indexTraverseLevel = 1; private boolean indexIncludeCollections = true; private Property<Date> timeStamp; private List<Property<? extends Serializable>> properties = new ArrayList<Property<? extends Serializable>>(); private View defaultView; private PersisterTriggers trigger; protected Entity(String name) { this(name, name, "ID", name + "_ID_SQ"); } protected Entity(String name, String tableName, String primaryKeyName) { this(name, tableName, primaryKeyName, primaryKeyName + "_SQ"); } protected Entity(String name, String tableName, String primaryKeyName, String sequenceName) { super(name); setLocalizationKey(name); Property<Integer> pk = new Property<Integer>(this.getId() + "." + "PRIMARY_KEY", Integer.class, 0, true, this, false, null); primaryKey = pk; primaryKey.setLocalizationKey("ID"); Property<Date> ts = new Property<Date>(this.getId() + "." + TIMESTAMP_NAME, Date.class, 0, false, this, false, null); timeStamp = ts; timeStamp.setLocalizationKey("timeStamp"); PersisterFactory.getPersister().registerEntity(this, tableName); PersisterFactory.getPersister().registerPrimaryKey(this, primaryKey, primaryKeyName, sequenceName); PersisterFactory.getPersister().registerTimestamp(this, timeStamp, TIMESTAMP_NAME); } public boolean isIndexIncludeCollections() { return indexIncludeCollections; } public void setIndexIncludeCollections(boolean indexIncludeCollections) { this.indexIncludeCollections = indexIncludeCollections; } public int getIndexTraverseLevel() { return indexTraverseLevel; } public void setIndexTraverseLevel(int indexTraverseLevel) { this.indexTraverseLevel = indexTraverseLevel; } public boolean isIndexed() { return indexed; } public void setIndexed(boolean indexed) { this.indexed = indexed; } protected Entity map(String tableName, String primaryKeyName, String sequenceName) { PersisterFactory.getPersister().registerEntity(this, tableName); PersisterFactory.getPersister().registerPrimaryKey(this, primaryKey, primaryKeyName, sequenceName); PersisterFactory.getPersister().registerTimestamp(this, timeStamp, TIMESTAMP_NAME); return this; } public List<Property<? extends Serializable>> getProperties() { return properties; } private <X extends Serializable> Property<X> addProperty(String name, Class<X> type, double size, boolean required, boolean virtual, String formatPattern) { Property<X> property = new Property<X>(this.getId() + "." + name, type, size, required, this, virtual, formatPattern); property.setLocalizationKey(this.getId() + "." + name); properties.add(property); if (!virtual) { PersisterFactory.getPersister().registerProperty(this, property, name); } return property; } public Property<String> stringProperty(String name, int size, boolean required) { return addProperty(name, String.class, size, required, false, null); } public Property<String> stringProperty(String name, boolean required) { return addProperty(name, String.class, 255, required, false, null); } public Property<String> stringProperty(String name, int size) { return stringProperty(name, size, false); } public Property<String> stringProperty(String name) { return stringProperty(name, 255); } public Property<String> virtualStringProperty(String name) { return addProperty(name, String.class, 30000, false, true, null); } public Property<String> virtualTextProperty(String name) { return addProperty(name, String.class, 0, false, true, null); } public Property<String> textProperty(String name) { return addProperty(name, String.class, 0, false, false, null); } public Property<Boolean> booleanProperty(String name, boolean required) { return addProperty(name, Boolean.class, 0, required, false, null); } public Property<Boolean> booleanProperty(String name) { return booleanProperty(name, false); } public Property<Boolean> virtualBooleanProperty(String name) { return addProperty(name, Boolean.class, 0, false, true, null); } public Property<BigDecimal> numericProperty(String name, double size, boolean required) { return addProperty(name, BigDecimal.class, size, required, false, null); } public Property<BigDecimal> numericProperty(String name) { return numericProperty(name, 10.2, false); } public Property<BigDecimal> virtualNumericProperty(String name, double size) { return addProperty(name, BigDecimal.class, size, false, true, null); } public Property<BigDecimal> virtualNumericProperty(String name) { return virtualNumericProperty(name, 10.2); } public Property<Integer> integerProperty(String name, boolean required) { return addProperty(name, Integer.class, 10.0, required, false, null); } public Property<Integer> integerProperty(String name) { return integerProperty(name, false); } public Property<Integer> virtualIntegerProperty(String name) { return addProperty(name, Integer.class, 10.0, false, true, null); } public Property<Date> dateProperty(String name, boolean required, String formatPattern) { return addProperty(name, Date.class, 0, required, false, formatPattern); } public Property<Date> dateProperty(String name, boolean required) { return dateProperty(name, required, null); } public Property<Date> dateProperty(String name) { return dateProperty(name, false); } public Property<Date> virtualDateProperty(String name) { return addProperty(name, Date.class, 0, false, true, null); } public BinaryProperty binaryProperty(String name) { BinaryProperty property = new BinaryProperty(this.getId() + "." + name, this); property.setLocalizationKey(this.getId() + "." + name); properties.add(property); PersisterFactory.getPersister().registerProperty(this, property, name); return property; } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name) { return referenceProperty(referredEntity, name, name); } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name, boolean required) { return referenceProperty(referredEntity, name, name, required); } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name, String mapping) { return referenceProperty(referredEntity, name, mapping, null); } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name, String mapping, boolean required) { return referenceProperty(referredEntity, name, mapping, null, required); } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name, String mapping, String indexName) { return referenceProperty(referredEntity, name, mapping, indexName, false); } public <T extends Entity> Reference<T> referenceProperty(T referredEntity, String name, String mapping, String indexName, boolean required) { Reference<T> property = new Reference<T>(this.getId() + "." + name, referredEntity, this, required); property.setLocalizationKey(this.getId() + "." + name); properties.add(property); if (indexName == null) { PersisterFactory.getPersister().registerReference(this, property, mapping, referredEntity); } else { PersisterFactory.getPersister().registerReference(this, property, mapping, referredEntity, indexName); } return property; } public <T extends Entity> Collection<T> collectionProperty(T referredEntity, String name) { return collectionProperty(referredEntity, name, name); } public <T extends Entity> Collection<T> collectionProperty(T referredEntity, String name, String mapping) { return collectionProperty(referredEntity, name, mapping, null); } public <T extends Entity> Collection<T> collectionProperty(T referredEntity, String name, String mapping, String indexName) { Collection<T> property = new Collection<T>(this.getId() + "." + name, referredEntity, this); property.setLocalizationKey(this.getId() + "." + name); properties.add(property); PersisterFactory.getPersister().registerReference(referredEntity, property, mapping, this, indexName); return property; } public <T extends Entity> Collection<T> reverseCollectionProperty(String name, T referredEntity, Reference<? extends Entity> referringColumn) { Collection<T> property = new Collection<T>(this.getId() + "." + name, referredEntity, this); property.setLocalizationKey(this.getId() + "." + name); properties.add(property); PersisterFactory.getPersister().registerReverseCollection(property, referringColumn); return property; } public Property<Integer> getPrimaryKey() { return primaryKey; } public Property<Date> getTimeStamp() { return timeStamp; } public void addIndex(String name, boolean unique, Property<?>... properties) { PersisterFactory.getPersister().registerIndex(this, name, unique, properties); } public PersisterTriggers getPersisterTriggers() { if (this.trigger == null) { this.setPersistersTriggers(new PersisterTriggers.Default()); } return this.trigger; } public Entity setPersistersTriggers(PersisterTriggers triggers) { this.trigger = triggers; return this; } public synchronized View view() { if (defaultView == null) { defaultView = initDefaultView(); } return defaultView; } /** * Create the default view for this entity. The view contains all properties * except References, Collections and BinaryData. It has simple form with * VerticalPanel, containing default widgets for all properties, obtained * from Property.widget() method * * @return The default view * @see Property */ protected View initDefaultView() { View retval = new View(this); Form form = new Form(true); Panel layout = Panel.column(); for (Property<? extends Serializable> prop : properties) { if (!((prop instanceof Reference) || (prop instanceof Collection) || (prop.getType().equals(BinaryData.class)))) { retval.addProperty(prop); } layout.add(prop.widget()); } form.setLayout(layout); retval.setForm(form); if (retval.getProperties().size() > 0) { Property<? extends Serializable> prop = retval.getProperties().get(0); retval.addSortDescriptor("Default", prop.getLocalizationKey(), SortItem.ascending(prop)); } return retval; } public View inheritanceView(View masterView, Property<String> discriminator, Enum<?> value) { View view = new SubView(masterView, discriminator, value); PersisterFactory.getPersister().addInheritanceIndex(this, discriminator); return view; } }