/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.catalog.api.impl; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.hibernate.criterion.Projection; import org.hibernate.criterion.ProjectionList; import org.hibernate.criterion.Projections; /** * <p>Title: ProjectionListAccumulator</p> * <p>Description: An accumulator for projections</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.catalog.api.impl.ProjectionListAccumulator</code></p> */ public class ProjectionListAccumulator implements Parsed<ProjectionList> { /** The projection list to accumulate against */ protected final ProjectionList projectionList = Projections.projectionList(); /** The RowCount projection. Requires no params. */ public static final String PROJ_ROWCOUNT = "rc"; /** The average projection. Param: the property to average */ public static final String PROJ_AVG = "avg"; /** The max projection. Param: the property to max */ public static final String PROJ_MAX = "max"; /** The min projection. Param: the property to min */ public static final String PROJ_MIN = "min"; /** The count projection. Param: the property to count */ public static final String PROJ_COUNT = "cnt"; /** The count distinct projection. Param: the property to distinct count */ public static final String PROJ_COUNTDIST = "cntd"; /** The group projection. Param: the property to group */ public static final String PROJ_GRP = "grp"; /** The sum projection. Param: the property to sum */ public static final String PROJ_SUM = "sum"; /** A map of projections method handles keyed by op name */ private static Map<String, MethodHandle> projectionHandles = new HashMap<String, MethodHandle>(); static { saveHandle(PROJ_SUM, Projections.class, "sum", String.class); saveHandle(PROJ_GRP, Projections.class, "groupProperty", String.class); saveHandle(PROJ_COUNTDIST, Projections.class, "countDistinct", String.class); saveHandle(PROJ_COUNT, Projections.class, "count", String.class); saveHandle(PROJ_MIN, Projections.class, "min", String.class); saveHandle(PROJ_MAX, Projections.class, "max", String.class); saveHandle(PROJ_AVG, Projections.class, "avg", String.class); saveHandle(PROJ_ROWCOUNT, Projections.class, "rowCount"); System.out.println("Op Codes:" + projectionHandles.keySet()); } public static void main(String[] args) {} private static void saveHandle(String key, Class<?> clazz, String name, Class<?>...pattern){ try { Method m = null; try { m = clazz.getDeclaredMethod(name, pattern); } catch (NoSuchMethodException nex) { m = clazz.getMethod(name, pattern); } saveHandle(key, m); } catch (Exception ex) { throw new RuntimeException(ex); } } private static void saveHandle(String dkey, Method method){ try { MethodType desc = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); MethodHandle mh = MethodHandles.lookup().findStatic(method.getDeclaringClass(), method.getName(), desc); projectionHandles.put(dkey, mh); } catch (Exception ex) { ex.printStackTrace(System.err); throw new RuntimeException(ex); } } /** * {@inheritDoc} * @see org.helios.apmrouter.catalog.api.impl.Parsed#applyPrimitive(java.lang.String, java.lang.Object) */ @Override public Parsed<ProjectionList> applyPrimitive(String op, Object value) { MethodHandle mh = projectionHandles.get(op); Projection projection = null; try { if(mh.type().parameterCount()<1) { projection = (Projection) mh.invoke(); } else { if(value.getClass().isArray()) { int argCnt = Array.getLength(value); if(argCnt==1) { projection = (Projection)mh.invoke(Array.get(value, 0)); } else { Object[] args = new Object[argCnt]; System.arraycopy(value, 0, args, 0, args.length); projection = (Projection)mh.invoke(args); } } else { projection = (Projection)mh.invoke(value); } } projectionList.add(projection); } catch (Throwable ex) { throw new RuntimeException(ex); } return this; } /** * {@inheritDoc} * @see org.helios.apmrouter.catalog.api.impl.Parsed#get() */ @Override public ProjectionList get() { return projectionList; } }