Bug 11522 - New agent manager

refine SearchCirteria2
This commit is contained in:
frank 2011-10-05 16:49:47 -07:00
parent 89e04458b6
commit 2b0afe505d
6 changed files with 221 additions and 20 deletions

View File

@ -6,6 +6,7 @@ import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
@ -51,7 +52,6 @@ public class SearchCriteria2Test extends TestCase {
s_logger.info("Host id: " + vo.getId() + " is Disconnected");
}
SearchCriteria2<VMInstanceVO, VMInstanceVO> sc1 = SearchCriteria2.create(VMInstanceVO.class);
sc1.addAnd(sc1.getEntity().getState(), Op.EQ, VirtualMachine.State.Running);
List<VMInstanceVO> vms = sc1.list();
@ -59,6 +59,14 @@ public class SearchCriteria2Test extends TestCase {
s_logger.info("Vm name:" + vm.getInstanceName());
}
SearchCriteria2<HostVO, Long> sc3 = SearchCriteria2.create(HostVO.class, Long.class);
sc3.selectField(sc3.getEntity().getId());
sc3.addAnd(sc3.getEntity().getStatus(), Op.EQ, Status.Disconnected);
sc3.addAnd(sc3.getEntity().getType(), Op.EQ, Host.Type.Routing);
List<Long> hostIds = sc3.list();
for (Long id : hostIds) {
s_logger.info("Host Id is " + id);
}
}
@Override

View File

@ -236,5 +236,9 @@ public interface GenericDao<T, ID extends Serializable> {
boolean lockInLockTable(String id, int seconds);
boolean unlockFromLockTable(String id);
<K> SearchCriteria2 createSearchCriteria2(Class<K> resultType);
SearchCriteria2 createSearchCriteria2();
}

View File

@ -1653,5 +1653,22 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
SearchBuilder<T> builder = createSearchBuilder();
return builder.create();
}
@Override @DB(txn=false)
public <K> SearchCriteria2 createSearchCriteria2(Class<K> resultType) {
final T entity = (T)_searchEnhancer.create();
final Factory factory = (Factory)entity;
SearchCriteria2 sc = new SearchCriteria2(entity, resultType, _allAttributes, this);
factory.setCallback(0, sc);
return sc;
}
@Override @DB(txn=false)
public SearchCriteria2 createSearchCriteria2() {
final T entity = (T)_searchEnhancer.create();
final Factory factory = (Factory)entity;
SearchCriteria2 sc = new SearchCriteria2(entity, (Class<T>)entity.getClass(), _allAttributes, this);
factory.setCallback(0, sc);
return sc;
}
}

View File

@ -115,7 +115,7 @@ public class SearchCriteria<K> {
private final Map<String, Attribute> _attrs;
private final ArrayList<Condition> _conditions;
private ArrayList<Condition> _additionals = null;
private final HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
private HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
private int _counter;
private HashMap<String, JoinBuilder<SearchCriteria<?>>> _joins;
private final ArrayList<Select> _selects;
@ -139,6 +139,21 @@ public class SearchCriteria<K> {
_selectType = null;
}
protected SearchCriteria(final Map<String, Attribute> attrs, ArrayList<GenericSearchBuilder.Condition> conditions, ArrayList<Select> selects, SelectType selectType, Class<K> resultType, HashMap<String, Object[]> params) {
this._attrs = attrs;
this._conditions = conditions;
this._selects = selects;
this._selectType = selectType;
this._resultType = resultType;
this._params = params;
this._builder = null;
this._additionals = new ArrayList<Condition>();
this._counter = 0;
this._joins = null;
this._groupBy = null;
this._groupByValues = null;
}
protected SearchCriteria(GenericSearchBuilder<?, K> sb) {
this._builder = null;
this._attrs = sb._attrs;

View File

@ -1,42 +1,188 @@
package com.cloud.utils.db;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class SearchCriteria2<T, K> extends SearchCriteria<K> {
GenericSearchBuilder<?, K> _sb;
import javax.persistence.Transient;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.cloud.utils.db.GenericSearchBuilder.Condition;
import com.cloud.utils.db.GenericSearchBuilder.Select;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.SearchCriteria.SelectType;
public class SearchCriteria2<T, K> implements SearchCriteriaService<T, K>, MethodInterceptor{
GenericDao<? extends Serializable, ? extends Serializable> _dao;
final protected Map<String, Attribute> _attrs;
protected ArrayList<Attribute> _specifiedAttrs;
protected T _entity;
protected ArrayList<GenericSearchBuilder.Condition> _conditions;
protected ArrayList<Select> _selects;
private final HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
protected Class<K> _resultType;
protected SelectType _selectType;
protected Class<T> _entityBeanType;
protected SearchCriteria2(GenericSearchBuilder<?, K> sb, GenericDao<? extends Serializable, ? extends Serializable> dao) {
super(sb);
this._sb = sb;
this._dao = dao;
protected SearchCriteria2(T entity, Class<K> resultType, final Map<String, Attribute> attrs, GenericDao<? extends Serializable, ? extends Serializable> dao) {
_entityBeanType = (Class<T>)entity.getClass();
_dao = dao;
_resultType = resultType;
_attrs = attrs;
_entity = entity;
_conditions = new ArrayList<Condition>();
_specifiedAttrs = new ArrayList<Attribute>();
}
static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType, Class<K> resultType) {
GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
assert dao != null : "Can not find DAO for " + entityType.getName();
SearchCriteria2<T, K> sc = dao.createSearchCriteria2(resultType);
return sc;
}
static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType) {
GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
assert dao != null : "Can not find DAO for " + entityType.getName();
SearchBuilder<T> sb = (SearchBuilder<T>) dao.createSearchBuilder();
SearchCriteria2<T, K> sc = new SearchCriteria2(sb, dao);
return (SearchCriteria2<T, K>) sc;
}
public void selectField(Object... useless) {
_sb.selectField(useless);
SearchCriteria2<T, K> sc = dao.createSearchCriteria2();
return sc;
}
@Override
public void selectField(Object... useless) {
assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
assert _specifiedAttrs.size() > 0 : "You didn't specify any attributes";
if (_selects == null) {
_selects = new ArrayList<Select>();
}
for (Attribute attr : _specifiedAttrs) {
Field field = null;
try {
field = _resultType.getDeclaredField(attr.field.getName());
field.setAccessible(true);
} catch (SecurityException e) {
} catch (NoSuchFieldException e) {
}
_selects.add(new Select(Func.NATIVE, attr, field, null));
}
_specifiedAttrs.clear();
}
private void constructCondition(String conditionName, String cond, Attribute attr, Op op) {
assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
assert op != Op.SC : "Call join";
GenericSearchBuilder.Condition condition = new GenericSearchBuilder.Condition(conditionName, cond, attr, op);
_conditions.add(condition);
_specifiedAttrs.clear();
}
private void setParameters(String conditionName, Object... params) {
assert _conditions.contains(new Condition(conditionName)) : "Couldn't find " + conditionName;
_params.put(conditionName, params);
}
@Override
public void addAnd(Object useless, Op op, Object...values) {
String uuid = UUID.randomUUID().toString();
_sb.and(uuid, null, op);
this.setParameters(uuid, values);
constructCondition(uuid, " AND ", _specifiedAttrs.get(0), op);
setParameters(uuid, values);
}
@Override
public List<K> list() {
return (List<K>)_dao.search((SearchCriteria)this, null);
done();
SearchCriteria sc1 = createSearchCriteria();
if (isSelectAll()) {
return (List<K>)_dao.search(sc1, null);
} else {
return (List<K>)_dao.customSearch(sc1, null);
}
}
private boolean isSelectAll() {
return _selects == null || _selects.size() == 0;
}
public T getEntity() {
return (T) _sb.entity();
return (T) _entity;
}
private SearchCriteria<K> createSearchCriteria() {
return new SearchCriteria<K>(_attrs, _conditions, _selects, _selectType, _resultType, _params);
}
private void set(String name) {
Attribute attr = _attrs.get(name);
assert (attr != null) : "Searching for a field that's not there: " + name;
_specifiedAttrs.add(attr);
}
private void done() {
if (_entity != null) {
Factory factory = (Factory)_entity;
factory.setCallback(0, null);
_entity = null;
}
if (_selects == null || _selects.size() == 0) {
_selectType = SelectType.Entity;
assert _entityBeanType.equals(_resultType) : "Expecting " + _entityBeanType + " because you didn't specify any selects but instead got " + _resultType;
return;
}
for (Select select : _selects) {
if (select.field == null) {
assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
_selectType = SelectType.Single;
return;
}
if (select.func != null) {
_selectType = SelectType.Result;
return;
}
}
_selectType = SelectType.Fields;
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
String name = method.getName();
if (method.getAnnotation(Transient.class) == null) {
if (name.startsWith("get")) {
String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
set(fieldName);
return null;
} else if (name.startsWith("is")) {
String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
set(fieldName);
return null;
} else {
name = name.toLowerCase();
for (String fieldName : _attrs.keySet()) {
if (name.endsWith(fieldName.toLowerCase())) {
set(fieldName);
return null;
}
}
assert false : "Perhaps you need to make the method start with get or is?";
}
}
return methodProxy.invokeSuper(object, args);
}
}

View File

@ -0,0 +1,11 @@
package com.cloud.utils.db;
import java.util.List;
import com.cloud.utils.db.SearchCriteria.Op;
public interface SearchCriteriaService<T, K> {
public void selectField(Object... useless);
public void addAnd(Object useless, Op op, Object...values);
public List<K> list();
}