package net.tccn.base.arango; import com.arangodb.ArangoCollection; import com.arangodb.ArangoDBException; import com.arangodb.ArangoDatabase; import com.arangodb.entity.DocumentCreateEntity; import javax.persistence.Table; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; /** * @author: liangxianyou at 2018/12/1 22:59. */ public abstract class Doc { private HashMap attr = new HashMap(); private String _id; private String _key; private Set _shows; private Map _order; public String getId() { return _id; } public void setId(String id) { this._id = id; } public String getKey() { return _key; } public void setKey(String key) { this._key = key; } public Doc set(String k, Object v) { attr.put(k, v); return this; } public V get(String k) { return (V)attr.get(k); } /*public T setShows(String... show) { if (_shows == null) { _shows = new HashSet<>(); } for (String s : show) { _shows.add(s); } return (T) this; }*/ public Set get_Shows() { return _shows; } /*public void set_Shows(Set shows) { this._shows = shows; }*/ public T setOrder(String col, int desc) { if (_order == null) { _order = new LinkedHashMap(); } _order.put(col, desc); return (T) this; } public Map getOrder() { return _order; } /*public void setOrder(Map order) { this._order = order; }*/ /*@Override public String toString() { //convert. String doc = convert.convertTo(this); if (attr.size() == 0) { return doc; } StringBuilder builder = new StringBuilder(); if (attr.size() != 0) { String attrStr = convert.convertTo(attr); builder.append("{"); builder.append(attrStr, 1, attrStr.length() - 1); builder.append(","); builder.append(doc, 1, doc.length()); //builder.append(doc.substring(1)); } return builder.toString(); }*/ private Function fieldName = (s) -> { return s.replace("get", "").substring(0, 1).toLowerCase() + s.substring(4); }; /** * 提取Doc 属性到 Map,用于存贮到Arango中 * 提取规则: * 1、将doc中自带非空( !=null )属性提取都map中, * 2、将attr中属性覆盖到map中(如果attr中存在同名属性,attr为主) * @return */ public Map toDoc() { HashMap clone = (HashMap) attr.clone(); Class type = this.getClass(); Method[] methods = type.getDeclaredMethods(); for (Method method : methods) { String name = method.getName(); if (name.startsWith("get") && method.getParameterCount() == 0) { //Type mt = method.getAnnotatedReturnType().getType(); try { //System.out.println(method.getName()); Object v = method.invoke(this); if (v != null) { clone.put(fieldName.apply(name), v); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } return clone; } //--------------------------------------------------------------------------------------------------- private ArangoSource arangoSource; private ArangoDatabase db; private ArangoCollection collection; private static ConcurrentHashMap daos = new ConcurrentHashMap(); public Doc() { Table table = this.getClass().getAnnotation(Table.class); String sourceName = null; Source source = this.getClass().getAnnotation(Source.class); if (source != null) { sourceName = source.name(); } arangoSource = ArangoSource.use(sourceName); this.db = arangoSource.db(table.catalog()); this.collection = arangoSource.collection(this); } public final static T dao(Class type) { if (daos.get(type) == null) { try { daos.put(type, type.newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return (T) daos.get(type); } //ok public T save() { DocumentCreateEntity tmap = collection.insertDocument(this.toDoc()); this.setId(tmap.getId()); this.setKey(tmap.getKey()); return (T) this; } //ok public void update() { collection.updateDocument(this.getKey(), this.toDoc()); } public T findFirst(T t) { return findFirst(arangoSource.parseAql(t, 0, 1), (Class) t.getClass()); } public List find() { return find((T) this, 0, 1000); } public List find(T t) { return find(t, 0, 1000); } public List find(T t, int offset, int pn) { return find(arangoSource.parseAql(t, offset, pn), (Class)this.getClass()); } public List find(String aql, Class clazz) { try { return db.query(aql, clazz).asListRemaining(); } catch (ArangoDBException e) { System.out.println(aql); e.printStackTrace(); ArangoSource.init(); } return db.query(aql, clazz).asListRemaining(); } public T findFirst(String aql, Class clazz) { try { return db.query(aql, clazz).first(); } catch (ArangoDBException e) { System.out.println(aql); e.printStackTrace(); ArangoSource.init(); } return db.query(aql, clazz).first(); } public long count() { return count(this); } public long count(T t) { return db.query(arangoSource.parseAqlCount(t), long.class).first(); } //ok public T findByKey(Object key) { return (T) collection.getDocument(String.valueOf(key), this.getClass()); } //ok public void delete() { collection.deleteDocument(getKey()); } public void delete(Collection key) { collection.deleteDocuments(key); } }