001package io.ebean.enhance.common; 002 003import java.util.HashSet; 004import java.util.List; 005import java.util.Set; 006import java.util.StringJoiner; 007import java.util.TreeSet; 008 009/** 010 * Summary of the enhancement. 011 */ 012public class SummaryInfo { 013 014 private final List<String> loadedResources; 015 private final Set<String> entities = new HashSet<>(); 016 private final Set<String> queryBeans = new HashSet<>(); 017 private final Set<String> queryBeanCallers = new HashSet<>(); 018 private final Set<String> transactional = new HashSet<>(); 019 020 SummaryInfo(List<String> loadedResources) { 021 this.loadedResources = loadedResources; 022 } 023 024 /** 025 * Remove from queryBeanCallers the queryBeans (due to profile location enhancement). 026 */ 027 SummaryInfo prepare() { 028 for (String queryBean : queryBeans) { 029 queryBeanCallers.remove(queryBean); 030 queryBeanCallers.remove(queryBean + "$Companion"); 031 } 032 return this; 033 } 034 035 /** 036 * Return true if there was nothing enhanced. 037 */ 038 public boolean isEmpty() { 039 return entities.isEmpty() && queryBeans.isEmpty() && queryBeanCallers.isEmpty() && transactional.isEmpty(); 040 } 041 042 public boolean hasEntities() { 043 return !entities.isEmpty(); 044 } 045 046 public boolean hasQueryBeans() { 047 return !queryBeans.isEmpty(); 048 } 049 050 public boolean hasTransactional() { 051 return !transactional.isEmpty(); 052 } 053 054 public boolean hasQueryCallers() { 055 return !queryBeanCallers.isEmpty(); 056 } 057 058 059 public String toString() { 060 return " entities:" + entities + " queryBeans:" + queryBeans + " tqb:" + transactional; 061 } 062 063 void addTransactional(String className) { 064 transactional.add(className); 065 } 066 067 void addEntity(String className) { 068 entities.add(className); 069 } 070 071 void addQueryBean(String className) { 072 queryBeans.add(className); 073 } 074 075 void addQueryBeanCaller(String className) { 076 queryBeanCallers.add(className); 077 } 078 079 private String summary(String prefix, Set<String> beans) { 080 return new SumOut(beans).summary(prefix); 081 } 082 083 /** 084 * Return the manifest resource paths that were loaded. 085 */ 086 public List<String> loadedResources() { 087 return loadedResources; 088 } 089 090 /** 091 * Return a summary of the entities enhanced. 092 */ 093 public String entities() { 094 return summary(" Entities", entities); 095 } 096 097 /** 098 * Return a summary of the query beans enhanced. 099 */ 100 public String queryBeans() { 101 return summary(" QueryBeans", queryBeans); 102 } 103 104 /** 105 * Return a summary of the beans enhanced that call query beans. 106 */ 107 public String queryCallers() { 108 return summary("Query Callers", queryBeanCallers); 109 } 110 111 /** 112 * Return a summary of the beans with transactional enhanced. 113 */ 114 public String transactional() { 115 return summary("Transactional", transactional); 116 } 117 118 /** 119 * Helper that trims off the common package prefix to shorten the output. 120 */ 121 static class SumOut { 122 123 private final Set<String> beans; 124 private final Set<String> trimmedBeans; 125 private String[] commonAsArray; 126 private String commonPrefix; 127 128 SumOut(Set<String> beans) { 129 this.beans = beans; 130 initCommonPrefix(); 131 trimmedBeans = trimmedBeans(); 132 } 133 134 String sizeOut(int size) { 135 return " (" + size + ")" + ((size < 9) ? " " : ""); 136 } 137 138 String summary(String prefix) { 139 return prefix + sizeOut(beans.size()) + " pkgs[" + commonPrefix + "] beans" + trimmedBeans.toString(); 140 } 141 142 String commonPackage() { 143 return commonPrefix; 144 } 145 146 String beans() { 147 return trimmedBeans.toString(); 148 } 149 150 private void initCommonPrefix() { 151 if (beans.isEmpty()) { 152 commonPrefix = ""; 153 } else { 154 for (String bean : beans) { 155 final String beanPrefix = prefix(bean); 156 if (commonPrefix == null) { 157 commonPrefix = beanPrefix; 158 commonAsArray = beanPrefix.split("/"); 159 } else { 160 common(beanPrefix); 161 } 162 } 163 } 164 } 165 166 private void common(String beanPrefix) { 167 if (beanPrefix.equals(commonPrefix)) { 168 return; 169 } 170 171 final String[] elements = beanPrefix.split("/"); 172 int min = Math.min(commonAsArray.length, elements.length); 173 for (int i = 0; i < min; i++) { 174 if (!elements[i].equals(commonAsArray[i])) { 175 commonFor(i); 176 return; 177 } 178 } 179 if (commonAsArray.length != min) { 180 commonFor(min); 181 } 182 } 183 184 private void setCommonPrefix(String beanPrefix) { 185 commonPrefix = beanPrefix; 186 commonAsArray = beanPrefix.split("/"); 187 } 188 189 private void commonFor(int pos) { 190 StringJoiner joiner = new StringJoiner("/"); 191 for (int i = 0; i < pos; i++) { 192 joiner.add(commonAsArray[i]); 193 } 194 setCommonPrefix(joiner.toString()); 195 } 196 197 String prefix(String bean) { 198 final int pos = bean.lastIndexOf('/'); 199 return (pos == -1) ? bean : bean.substring(0, pos); 200 } 201 202 private Set<String> trimmedBeans() { 203 if (beans.isEmpty()) { 204 return beans; 205 } 206 Set<String> temp = new TreeSet<>(); 207 int trimLen = commonPrefix.length() + 1; 208 if (trimLen == 1) { 209 trimLen = 0; 210 } 211 for (String bean : beans) { 212 if (bean.length() > trimLen) { 213 bean = bean.substring(trimLen); 214 } 215 temp.add(bean); 216 } 217 return temp; 218 } 219 220 } 221}