001/* 002 * JKNIV, SQLegance keeping queries maintainable. 003 * 004 * Copyright (C) 2017, the original author or authors. 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software Foundation, Inc., 018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 019 */ 020package net.sf.jkniv.whinstone.classification; 021 022import java.sql.ResultSet; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.HashSet; 026import java.util.LinkedHashMap; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030 031import net.sf.jkniv.reflect.beans.CapitalNameFactory; 032import net.sf.jkniv.reflect.beans.Capitalize; 033import net.sf.jkniv.reflect.beans.ObjectProxy; 034import net.sf.jkniv.reflect.beans.ObjectProxyFactory; 035import net.sf.jkniv.whinstone.classification.Transformable.TransformableType; 036 037/** 038 * Create group of objects with a tabular result {@code <R>}. 039 * 040 * @param <T> type of grouped objects 041 * @param <R> The driver result of a query like {@link ResultSet} 042 * 043 * @author alisson 044 */ 045public class GroupingBy<T, R> implements Groupable<T, R> 046{ 047 private static final Capitalize CAPITAL_GETTER = CapitalNameFactory.getInstanceOfGetter(); 048 private final Transformable<R> transform; 049 private final Map<String, T> grouped; 050 private final List<String> keys; 051 private final Class<T> type; 052 053 public GroupingBy(List<String> keys, Class<T> type, Transformable.TransformableType transformableType) 054 { 055 this.grouped = new LinkedHashMap<String, T>(); 056 this.keys = keys; 057 this.type = type; 058 if (transformableType == TransformableType.MAP) 059 this.transform = (Transformable<R>) new MapTransform(); 060 //else if (transformableType == TransformableType.RESULT_SET) 061 // this.transform = (Transformable<R>) new ResultSetTransform(); 062 else 063 this.transform = (Transformable<R>) new ObjectTransform(); 064 } 065 066 public GroupingBy(List<String> keys, Class<T> type, Transformable<R> transform) 067 { 068 this.grouped = new LinkedHashMap<String, T>(); 069 this.keys = keys; 070 this.type = type; 071 this.transform = transform; 072 } 073 074 /* (non-Javadoc) 075 * @see net.sf.jkniv.sqlegance.classifier.Groupable#classifier(R) 076 */ 077 @Override 078 @SuppressWarnings({ "rawtypes" }) 079 public void classifier(R row) 080 { 081 ObjectProxy<R> rowProxy = ObjectProxyFactory.of(row); 082 StringBuilder keySb = new StringBuilder(); 083 for (String k : this.keys) 084 { 085 Object keyValue = null; 086 if (row instanceof Map) 087 keyValue = ((Map) row).get(k); 088 else 089 keyValue = rowProxy.invoke(CAPITAL_GETTER.does(k)); 090 091 if (keyValue != null) 092 keySb.append(keyValue.toString()); 093 } 094 String key = keySb.toString(); 095 T object = grouped.get(key); 096 if (object == null) 097 { 098 object = transform.transform(row, type); 099 grouped.put(key, object); 100 } 101 else 102 { 103 //System.out.println(" ROW -> " + row); 104 //System.out.println("OBJECT -> " + object); 105 transform.transform(row, object); 106 } 107 } 108 109 /* (non-Javadoc) 110 * @see net.sf.jkniv.sqlegance.classifier.Groupable#asCollection() 111 */ 112 @Override 113 public Collection<T> asCollection() 114 { 115 return grouped.values(); 116 } 117 118 /* (non-Javadoc) 119 * @see net.sf.jkniv.sqlegance.classifier.Groupable#asList() 120 */ 121 @Override 122 public List<T> asList() 123 { 124 return new ArrayList<T>(grouped.values()); 125 } 126 127 /* (non-Javadoc) 128 * @see net.sf.jkniv.sqlegance.classifier.Groupable#asSet() 129 */ 130 @Override 131 public Set<T> asSet() 132 { 133 return new HashSet<T>(grouped.values()); 134 } 135 136}