Procházet zdrojové kódy

use constants for uuid/ctime/mtime. improve default search field type bounds.

tags/2.0.1
Jonathan Cobb před 4 roky
rodič
revize
7c53947a09
15 změnil soubory, kde provedl 95 přidání a 39 odebrání
  1. +5
    -1
      wizard-common/src/main/java/org/cobbzilla/wizard/model/Identifiable.java
  2. +6
    -4
      wizard-common/src/main/java/org/cobbzilla/wizard/model/IdentifiableBase.java
  3. +8
    -5
      wizard-common/src/main/java/org/cobbzilla/wizard/model/SqlDefaultSearchField.java
  4. +28
    -5
      wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java
  5. +16
    -4
      wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityFieldType.java
  6. +4
    -1
      wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/StandardModelVerifyLog.java
  7. +1
    -1
      wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java
  8. +2
    -1
      wizard-common/src/main/java/org/cobbzilla/wizard/model/search/SearchField.java
  9. +2
    -1
      wizard-common/src/main/java/org/cobbzilla/wizard/model/search/SearchQuery.java
  10. +6
    -5
      wizard-server/src/main/java/org/cobbzilla/wizard/dao/AbstractCRUDDAO.java
  11. +3
    -2
      wizard-server/src/main/java/org/cobbzilla/wizard/dao/AbstractChildCRUDDAO.java
  12. +4
    -2
      wizard-server/src/main/java/org/cobbzilla/wizard/dao/SqlViewSearchableDAO.java
  13. +6
    -5
      wizard-server/src/main/java/org/cobbzilla/wizard/dao/shard/AbstractShardedDAO.java
  14. +2
    -1
      wizard-server/src/main/java/org/cobbzilla/wizard/model/anon/AnonScrubber.java
  15. +2
    -1
      wizard-server/src/main/java/org/cobbzilla/wizard/model/anon/AnonTable.java

+ 5
- 1
wizard-common/src/main/java/org/cobbzilla/wizard/model/Identifiable.java Zobrazit soubor

@@ -16,9 +16,13 @@ public interface Identifiable extends Serializable {

int UUID_MAXLEN = BasicConstraintConstants.UUID_MAXLEN;

String CTIME = "ctime";
String MTIME = "mtime";

String ENTITY_TYPE_HEADER_NAME = "ZZ-TYPE";

String[] IGNORABLE_UPDATE_FIELDS = { "uuid", "name", "children", "ctime", "mtime" };
String[] IGNORABLE_UPDATE_FIELDS = { UUID, "name", "children", CTIME, MTIME };

default String[] excludeUpdateFields(boolean strict) { return StringUtil.EMPTY_ARRAY; }

String getUuid();


+ 6
- 4
wizard-common/src/main/java/org/cobbzilla/wizard/model/IdentifiableBase.java Zobrazit soubor

@@ -20,14 +20,16 @@ import javax.persistence.Transient;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static java.util.UUID.randomUUID;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
import static org.cobbzilla.util.reflect.ReflectionUtil.copy;
import static org.cobbzilla.util.string.StringUtil.uncapitalize;

@MappedSuperclass @Slf4j
public class IdentifiableBase implements Identifiable {

public String simpleName () { return getClass().getSimpleName(); }
public String propName () { return StringUtil.uncapitalize(getClass().getSimpleName()); }
public String propName () { return uncapitalize(getClass().getSimpleName()); }

public String tableName () { return ImprovedNamingStrategy.INSTANCE.classToTableName(getClass().getName()); }
public String tableName (String className) { return ImprovedNamingStrategy.INSTANCE.classToTableName(className); }
@@ -74,7 +76,7 @@ public class IdentifiableBase implements Identifiable {

@Override public void beforeUpdate() { setMtime(); }

public void initUuid() { setUuid(java.util.UUID.randomUUID().toString()); }
public void initUuid() { setUuid(randomUUID().toString()); }

@Override public Identifiable update(Identifiable thing) { return update(thing, null); }

@@ -120,12 +122,12 @@ public class IdentifiableBase implements Identifiable {
public static String[] toUuidArray(List<? extends Identifiable> entities) {
return empty(entities)
? StringUtil.EMPTY_ARRAY
: (String[]) collectArray(entities, "uuid");
: (String[]) collectArray(entities, UUID);
}

public static List<String> toUuidList(Collection<? extends Identifiable> entities) {
if (empty(entities)) return Collections.emptyList();
return collectList(entities, "uuid");
return collectList(entities, UUID);
}

private static final Map<String, FieldTransformer> fieldTransformerCache = new ConcurrentHashMap<>();


+ 8
- 5
wizard-common/src/main/java/org/cobbzilla/wizard/model/SqlDefaultSearchField.java Zobrazit soubor

@@ -19,6 +19,7 @@ import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.reflect.ReflectionUtil.instantiate;
import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase;
import static org.cobbzilla.wizard.model.Identifiable.UUID;
import static org.cobbzilla.wizard.model.entityconfig.EntityFieldType.*;
import static org.cobbzilla.wizard.model.search.SearchField.*;

@@ -64,7 +65,7 @@ public class SqlDefaultSearchField implements SearchField {
if (ecForeignKey != null) {
fieldType = reference;
} else {
fieldType = ecField != null ? ecField.type() : guessFieldType(f);
fieldType = ecField != null && ecField.type() != none_set ? ecField.type() : guessFieldType(f);
}
}
}
@@ -88,10 +89,12 @@ public class SqlDefaultSearchField implements SearchField {
case reference:
bounds.addAll(asList(bindUuid(name())));
break;
case string: case email: case time_zone: case locale:
case ip4: case ip6: case http_url:
case us_phone: case us_state: case us_zip:
if (f.getName().equals("uuid")) {
case http_url: case us_phone: case us_state: case us_zip:
case email: case time_zone: case locale: case ip4: case ip6:
bounds.addAll(asList(bindNonSortableString(name())));
break;
case string:
if (f.getName().equals(UUID)) {
bounds.addAll(asList(bindUuid(name())));
} else {
bounds.addAll(asList(bindString(name())));


+ 28
- 5
wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java Zobrazit soubor

@@ -374,7 +374,7 @@ public class EntityConfig {
return this;
}

private String fieldNameFromAccessor(AccessibleObject accessor) throws IllegalArgumentException {
public static String fieldNameFromAccessor(AccessibleObject accessor) throws IllegalArgumentException {
if (accessor instanceof Field) return ((Field) accessor).getName();

if (accessor instanceof Method) {
@@ -451,7 +451,7 @@ public class EntityConfig {
if (ecToUpdate == null) return this;

final String fieldName = fieldPathParts.get(fieldPathParts.size() - 1);
ecToUpdate.fields.put(fieldName, buildFieldCfgFromAnnotation(fieldName, annotation.fieldDef(), fieldIndexes));
ecToUpdate.fields.put(fieldName, buildFieldCfgFromAnnotation(fieldName, annotation.fieldDef(), null, null, fieldIndexes));
return this;
}

@@ -524,8 +524,14 @@ public class EntityConfig {
}
}

private EntityFieldConfig buildFieldCfgFromAnnotation(String fieldName, ECField fieldAnnotation, Map<String, Integer> fieldIndexes) {
EntityFieldConfig cfg = new EntityFieldConfig().setMode(fieldAnnotation.mode()).setType(fieldAnnotation.type());
private EntityFieldConfig buildFieldCfgFromAnnotation(String fieldName,
ECField fieldAnnotation,
AccessibleObject accessor,
ECForeignKey fkAnnotation,
Map<String, Integer> fieldIndexes) {
final EntityFieldConfig cfg = new EntityFieldConfig()
.setMode(fieldAnnotation.mode())
.setType(getFieldType(fieldName, fieldAnnotation, accessor, fkAnnotation));
if (!empty(fieldAnnotation.name())) cfg.setName(fieldAnnotation.name());
if (!empty(fieldAnnotation.displayName())) cfg.setDisplayName(fieldAnnotation.displayName());
if (fieldAnnotation.length() > 0) cfg.setLength(fieldAnnotation.length());
@@ -540,13 +546,30 @@ public class EntityConfig {
return cfg;
}

private EntityFieldType getFieldType(String fieldName, ECField fieldAnnotation, AccessibleObject accessor, ECForeignKey fkAnnotation) {
if (fieldAnnotation.type() != EntityFieldType.none_set) return fieldAnnotation.type();
if (fkAnnotation != null) return EntityFieldType.reference;
if (accessor != null) {
if (accessor instanceof Field) {
return EntityFieldType.guessFieldType((Field) accessor);
} else if (accessor instanceof Method) {
return EntityFieldType.guessFieldType((Method) accessor);
} else {
log.warn("getFieldType("+fieldName+"): accessor is neither Field nor Method: "+accessor.getClass().getName());
}
}
log.warn("getFieldType("+fieldName+"): error detecting type, defaulting to 'string'");
return EntityFieldType.string;
}

private EntityFieldConfig buildFieldConfig(AccessibleObject accessor, Map<String, Integer> fieldIndexes) {
final String fieldName = fieldNameFromAccessor(accessor);
final EntityFieldConfig cfg = EntityFieldConfig.field(fieldName);

final ECField fieldAnnotation = annotationFromAccessor(accessor, ECField.class);
final ECForeignKey fkAnnotation = annotationFromAccessor(accessor, ECForeignKey.class);
if (fieldAnnotation != null) {
return buildFieldCfgFromAnnotation(fieldName, fieldAnnotation, fieldIndexes);
return buildFieldCfgFromAnnotation(fieldName, fieldAnnotation, accessor, fkAnnotation, fieldIndexes);
}

if (!(accessor instanceof Field) && !(accessor instanceof Method)) {


+ 16
- 4
wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityFieldType.java Zobrazit soubor

@@ -9,9 +9,13 @@ import org.cobbzilla.wizard.validation.Validator;

import javax.persistence.Column;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Locale;

import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.wizard.model.Identifiable.CTIME;
import static org.cobbzilla.wizard.model.Identifiable.MTIME;
import static org.cobbzilla.wizard.model.entityconfig.EntityConfig.fieldNameFromAccessor;

@AllArgsConstructor @Slf4j
public enum EntityFieldType {
@@ -149,13 +153,21 @@ public enum EntityFieldType {
}

public static EntityFieldType guessFieldType(Field f) {
switch (f.getType().getName()) {
return guessFieldType(f.getName(), f.getType());
}

public static EntityFieldType guessFieldType(Method m) {
return guessFieldType(fieldNameFromAccessor(m), m.getReturnType());
}

public static EntityFieldType guessFieldType(String name, Class<?> type) {
switch (type.getName()) {
case "boolean":
case "java.lang.Boolean":
return flag;
case "long":
case "java.lang.Long":
if (f.getName().equals("ctime") || f.getName().equals("mtime")) return epoch_time;
if (name.equals(CTIME) || name.equals(MTIME)) return epoch_time;
case "byte":
case "short":
case "int":
@@ -175,8 +187,8 @@ public enum EntityFieldType {
case "java.math.BigDecimal":
return decimal;
default:
if (f.getType().isEnum()) return string;
log.warn("guessFieldType: unrecognized type ("+f.getType().getName()+") for field: "+f.getName());
if (type.isEnum()) return string;
log.warn("guessFieldType: unrecognized type ("+type.getName()+") for field: "+name);
return null;
}
}


+ 4
- 1
wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/StandardModelVerifyLog.java Zobrazit soubor

@@ -23,6 +23,9 @@ import static org.cobbzilla.util.io.FileUtil.toFileOrDie;
import static org.cobbzilla.util.io.StreamUtil.loadResourceAsStringOrDie;
import static org.cobbzilla.util.json.JsonUtil.*;
import static org.cobbzilla.util.reflect.ReflectionUtil.*;
import static org.cobbzilla.wizard.model.Identifiable.UUID;
import static org.cobbzilla.wizard.model.Identifiable.CTIME;
import static org.cobbzilla.wizard.model.Identifiable.MTIME;
import static org.cobbzilla.wizard.model.entityconfig.ModelSetup.id;

@Slf4j
@@ -157,7 +160,7 @@ public class StandardModelVerifyLog implements ModelVerifyLog {
}
}

protected static final String[] EXCLUDED = {"uuid", "children", "entity", "ctime", "ctimeAge", "mtime", "mtimeAge", "entity"};
protected static final String[] EXCLUDED = {UUID, "children", CTIME, "ctimeAge", MTIME, "mtimeAge", "entity"};
protected static final Set<String> EXCLUDED_FIELDS = new HashSet<>(Arrays.asList(EXCLUDED));
protected Set<String> getExcludedFields() { return EXCLUDED_FIELDS; }



+ 1
- 1
wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java Zobrazit soubor

@@ -17,7 +17,7 @@ public @interface ECField {
String name() default "";
String displayName() default "";
EntityFieldMode mode() default EntityFieldMode.standard;
EntityFieldType type() default EntityFieldType.string;
EntityFieldType type() default EntityFieldType.none_set;
int length() default -1;
EntityFieldControl control() default EntityFieldControl.unset;
String options() default "";


+ 2
- 1
wizard-common/src/main/java/org/cobbzilla/wizard/model/search/SearchField.java Zobrazit soubor

@@ -59,13 +59,14 @@ public interface SearchField {
like.bind(name, SearchFieldType.string)
};
}
static SearchBound[] bindUuid(String name) {
static SearchBound[] bindNonSortableString(String name) {
return new SearchBound[] {
eq.bind(name, SearchFieldType.string),
ne.bind(name, SearchFieldType.string),
like.bind(name, SearchFieldType.string)
};
}
static SearchBound[] bindUuid(String name) { return bindNonSortableString(name); }
static SearchBound[] bindNullable(String name) { return new SearchBound[] { is_null.bind(name), not_null.bind(name) }; }

String name();


+ 2
- 1
wizard-common/src/main/java/org/cobbzilla/wizard/model/search/SearchQuery.java Zobrazit soubor

@@ -18,6 +18,7 @@ import java.util.Arrays;

import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.wizard.model.Identifiable.CTIME;

@NoArgsConstructor @Accessors(chain=true) @ToString
public class SearchQuery {
@@ -35,7 +36,7 @@ public class SearchQuery {

public static final int MAX_FILTER_LENGTH = 50;
public static final int MAX_SORTFIELD_LENGTH = 50;
public static final String DEFAULT_SORT_FIELD = "ctime";
public static final String DEFAULT_SORT_FIELD = CTIME;

public enum SortOrder {
ASC, DESC;


+ 6
- 5
wizard-server/src/main/java/org/cobbzilla/wizard/dao/AbstractCRUDDAO.java Zobrazit soubor

@@ -39,6 +39,7 @@ import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.json.JsonUtil.toJsonOrDie;
import static org.cobbzilla.util.reflect.ReflectionUtil.*;
import static org.cobbzilla.util.time.TimeUtil.formatDuration;
import static org.cobbzilla.wizard.model.Identifiable.MTIME;
import static org.hibernate.criterion.Restrictions.*;

@Transactional @Slf4j
@@ -57,19 +58,19 @@ public abstract class AbstractCRUDDAO<E extends Identifiable>
@Override public List<E> findAll() { return list(criteria()); }

@Transactional(readOnly=true)
@Override public E findByUuid(String uuid) { return findByUniqueField("uuid", uuid); }
@Override public E findByUuid(String uuid) { return findByUniqueField(Identifiable.UUID, uuid); }

@Transactional(readOnly=true)
public List<E> findByUuids(Collection<String> uuids) {
return empty(uuids) ? new ArrayList<E>() : findByFieldIn("uuid", uuids);
return empty(uuids) ? new ArrayList<E>() : findByFieldIn(Identifiable.UUID, uuids);
}
@Transactional(readOnly=true)
public List<E> findByUuids(Object[] uuids) {
return empty(uuids) ? new ArrayList<E>() : findByFieldIn("uuid", uuids);
return empty(uuids) ? new ArrayList<E>() : findByFieldIn(Identifiable.UUID, uuids);
}

@Transactional(readOnly=true)
public E findFirstByUuids(Collection<String> uuids) { return findFirstByFieldIn("uuid", uuids); }
public E findFirstByUuids(Collection<String> uuids) { return findFirstByFieldIn(Identifiable.UUID, uuids); }

@Transactional(readOnly=true)
@Override public boolean exists(String uuid) { return findByUuid(uuid) != null; }
@@ -337,7 +338,7 @@ public abstract class AbstractCRUDDAO<E extends Identifiable>
DetachedCriteria criteria = criteria().add(and(
ilike(likeField, likeValue)
));
if (mtime != null) criteria = criteria.add(gt("mtime", mtime));
if (mtime != null) criteria = criteria.add(gt(MTIME, mtime));
return list(criteria, 0, getFinderMaxResults());
}



+ 3
- 2
wizard-server/src/main/java/org/cobbzilla/wizard/dao/AbstractChildCRUDDAO.java Zobrazit soubor

@@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.cobbzilla.wizard.model.Identifiable.UUID;

public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends AbstractDAO<C> {

@@ -23,7 +24,7 @@ public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends Abs
}

@Override public C findByUuid(String uuid) {
return uniqueResult(Restrictions.eq("uuid", uuid));
return uniqueResult(Restrictions.eq(UUID, uuid));
}

@Override public C findByUniqueField(String field, Object value) {
@@ -48,7 +49,7 @@ public abstract class AbstractChildCRUDDAO<C extends ChildEntity, P> extends Abs
}

private P findParentByUuid(String parentId) {
return (P) uniqueResult(criteria(parentEntityClass).add(Restrictions.eq("uuid", parentId)));
return (P) uniqueResult(criteria(parentEntityClass).add(Restrictions.eq(UUID, parentId)));
}

public C create(String parentUuid, @Valid C child) {


+ 4
- 2
wizard-server/src/main/java/org/cobbzilla/wizard/dao/SqlViewSearchableDAO.java Zobrazit soubor

@@ -26,6 +26,8 @@ import static org.cobbzilla.util.daemon.ZillaRuntime.hashOf;
import static org.cobbzilla.util.reflect.ReflectionUtil.fieldsWithAnnotation;
import static org.cobbzilla.util.string.StringUtil.camelCaseToSnakeCase;
import static org.cobbzilla.util.string.StringUtil.sqlFilter;
import static org.cobbzilla.wizard.model.Identifiable.CTIME;
import static org.cobbzilla.wizard.model.Identifiable.UUID;

public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> {

@@ -76,7 +78,7 @@ public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> {
return die("buildBound: no bound defined for: "+bound);
}

default String getDefaultSort() { return "ctime"; }
default String getDefaultSort() { return CTIME; }

String getSelectClause(SearchQuery searchQuery);

@@ -104,7 +106,7 @@ public interface SqlViewSearchableDAO<T extends Identifiable> extends DAO<T> {
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "getRelated":
final Object uuid = ReflectionUtil.get(proxy, "uuid");
final Object uuid = ReflectionUtil.get(proxy, UUID);
if (uuid == null) return die("getRelated: no uuid found: "+proxy);
return this.getRelatedByUuid().get().computeIfAbsent(uuid.toString(), k -> new RelatedEntities());
}


+ 6
- 5
wizard-server/src/main/java/org/cobbzilla/wizard/dao/shard/AbstractShardedDAO.java Zobrazit soubor

@@ -36,12 +36,13 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

import static org.cobbzilla.util.daemon.Await.awaitAndCollect;
import static org.cobbzilla.util.daemon.Await.awaitFirst;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
import static org.cobbzilla.util.reflect.ReflectionUtil.*;
import static org.cobbzilla.util.security.ShaUtil.sha256_hex;
import static org.cobbzilla.wizard.model.Identifiable.UUID;
import static org.cobbzilla.wizard.resources.ResourceUtil.timeoutEx;
import static org.cobbzilla.util.daemon.Await.awaitAndCollect;
import static org.cobbzilla.util.daemon.Await.awaitFirst;
import static org.cobbzilla.wizard.util.SpringUtil.autowire;

@Transactional @Slf4j
@@ -299,10 +300,10 @@ public abstract class AbstractShardedDAO<E extends Shardable, D extends SingleSh
}

@Transactional(readOnly=true)
@Override public E findByUuid(final String uuid) { return findByUniqueField("uuid", uuid); }
@Override public E findByUuid(final String uuid) { return findByUniqueField(UUID, uuid); }

@Transactional(readOnly=true)
public E findByUuid(final String uuid, boolean useCache) { return findByUniqueField("uuid", uuid, useCache); }
public E findByUuid(final String uuid, boolean useCache) { return findByUniqueField(UUID, uuid, useCache); }

@Transactional(readOnly=true)
@Override public E findByUniqueField(String field, Object value) { return findByUniqueField(field, value, true); }
@@ -523,7 +524,7 @@ public abstract class AbstractShardedDAO<E extends Shardable, D extends SingleSh
}

@Override public void delete(String uuid) {
final List<D> daos = hashOn.equals("uuid") ? getAllDAOs(uuid) : getAllDAOs();
final List<D> daos = hashOn.equals(UUID) ? getAllDAOs(uuid) : getAllDAOs();
for (D dao : daos) dao.delete(uuid);
flushShardCache(uuid);
}


+ 2
- 1
wizard-server/src/main/java/org/cobbzilla/wizard/model/anon/AnonScrubber.java Zobrazit soubor

@@ -21,6 +21,7 @@ import java.util.Set;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.jdbc.ResultSetBean.row2map;
import static org.cobbzilla.wizard.model.Identifiable.UUID;
import static org.cobbzilla.wizard.model.ModelCryptUtil.getCryptor;

@Accessors(chain=true) @Slf4j
@@ -91,7 +92,7 @@ public class AnonScrubber {
die("anonymize: error handling table.column: " + errColumn, e);
}
}
update.setString(columns.length + 1, row.get("uuid").toString());
update.setString(columns.length + 1, row.get(UUID).toString());
if (update.executeUpdate() != 1) {
die("anonymize: error updating");
}


+ 2
- 1
wizard-server/src/main/java/org/cobbzilla/wizard/model/anon/AnonTable.java Zobrazit soubor

@@ -12,12 +12,13 @@ import java.util.List;
import java.util.Set;

import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.wizard.model.Identifiable.UUID;

@Accessors(chain=true) @ToString(of="table")
public class AnonTable {

@Getter @Setter private String table;
@Getter @Setter private String id = "uuid";
@Getter @Setter private String id = UUID;
@Getter @Setter private AnonColumn[] columns;
@Getter @Setter private boolean truncate = false;



Načítá se…
Zrušit
Uložit