// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 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; 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(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(); 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(); constructCondition(uuid, " AND ", _specifiedAttrs.get(0), op); setParameters(uuid, values); } @Override public List<K> list() { 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; } @Override public T getEntity() { 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); } @Override public <K> K find() { assert isSelectAll() : "find doesn't support select search"; done(); SearchCriteria sc1 = createSearchCriteria(); return (K)_dao.findOneBy(sc1); } }