package org.zstack.core.jsonlabel; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.GLock; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.db.UpdateQuery; import org.zstack.core.defer.Defer; import org.zstack.core.defer.Deferred; import org.zstack.utils.gson.JSONObjectUtil; import java.util.Collection; import java.util.concurrent.TimeUnit; /** * Created by xing5 on 2016/9/13. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class JsonLabel { @Autowired private DatabaseFacade dbf; private static String LOCK = JsonLabel.class.getName(); public JsonLabelInventory create(String key, Object obj, String resourceUuid) { JsonLabelVO vo = new JsonLabelVO(); vo.setLabelKey(key); if (obj instanceof String) { vo.setLabelValue(obj.toString()); } else { vo.setLabelValue(JSONObjectUtil.toJsonString(obj)); } vo.setResourceUuid(resourceUuid); vo = dbf.persistAndRefresh(vo); return JsonLabelInventory.valueOf(vo); } public JsonLabelInventory create(String key, Object obj) { return create(key, obj, null); } @Deferred public JsonLabelInventory createIfAbsent(String key, Object obj, String resourceUuid) { GLock lock = new GLock(LOCK, TimeUnit.MINUTES.toSeconds(2)); lock.lock(); Defer.defer(lock::unlock); SimpleQuery<JsonLabelVO> q = dbf.createQuery(JsonLabelVO.class); q.add(JsonLabelVO_.labelKey, Op.EQ, key); JsonLabelVO vo = q.find(); return vo == null ? create(key, obj, resourceUuid) : JsonLabelInventory.valueOf(vo); } public JsonLabelInventory createIfAbsent(String key, Object obj) { return createIfAbsent(key, obj, null); } public JsonLabelInventory get(String key) { SimpleQuery<JsonLabelVO> q = dbf.createQuery(JsonLabelVO.class); q.add(JsonLabelVO_.labelKey, Op.EQ, key); JsonLabelVO vo = q.find(); return vo == null ? null : JsonLabelInventory.valueOf(vo); } public <T> T get(String key, Class<T> clazz) { JsonLabelInventory inv = get(key); if (inv == null) { return null; } if (String.class.isAssignableFrom(clazz)) { return (T) inv.getLabelValue(); } else { return JSONObjectUtil.toObject(inv.getLabelValue(), clazz); } } public <T, K extends Collection> Collection getAsCollection(String key, Class<K> collectionClass, Class<T> clazz) { JsonLabelInventory inv = get(key); if (inv == null) { return null; } return JSONObjectUtil.toCollection(inv.getLabelValue(), collectionClass, clazz); } public void delete(String key) { UpdateQuery q = UpdateQuery.New(JsonLabelVO.class); q.condAnd(JsonLabelVO_.labelKey, Op.EQ, key); q.delete(); } public boolean exists(String key) { SimpleQuery<JsonLabelVO> q = dbf.createQuery(JsonLabelVO.class); q.add(JsonLabelVO_.labelKey, Op.EQ, key); return q.isExists(); } @Deferred public boolean atomicExists(String key) { GLock lock = new GLock(LOCK, TimeUnit.MINUTES.toSeconds(2)); lock.lock(); Defer.defer(lock::unlock); return exists(key); } @Deferred public void atomicDelete(String key) { GLock lock = new GLock(LOCK, TimeUnit.MINUTES.toSeconds(2)); lock.lock(); Defer.defer(lock::unlock); delete(key); } }