001package io.ebeaninternal.server.deploy; 002 003import io.ebean.Query; 004import io.ebean.Transaction; 005import io.ebean.bean.BeanCollection; 006import io.ebean.bean.BeanCollectionAdd; 007import io.ebean.bean.EntityBean; 008import io.ebean.common.BeanSet; 009import io.ebeaninternal.api.SpiEbeanServer; 010import io.ebeaninternal.api.json.SpiJsonWriter; 011 012import java.io.IOException; 013import java.util.LinkedHashSet; 014import java.util.Set; 015 016/** 017 * Helper specifically for dealing with Sets. 018 */ 019public class BeanSetHelp<T> extends BaseCollectionHelp<T> { 020 021 /** 022 * When attached to a specific many property. 023 */ 024 BeanSetHelp(BeanPropertyAssocMany<T> many) { 025 super(many); 026 } 027 028 /** 029 * For a query that returns a set. 030 */ 031 BeanSetHelp() { 032 super(); 033 } 034 035 @Override 036 public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) { 037 if (bc instanceof BeanSet<?>) { 038 BeanSet<?> beanSet = (BeanSet<?>) bc; 039 if (beanSet.getActualSet() == null) { 040 beanSet.setActualSet(new LinkedHashSet<>()); 041 } 042 return beanSet; 043 044 } else { 045 throw new RuntimeException("Unhandled type " + bc); 046 } 047 } 048 049 @Override 050 public BeanCollection<T> createEmptyNoParent() { 051 return new BeanSet<>(); 052 } 053 054 @Override 055 public BeanCollection<T> createEmpty(EntityBean ownerBean) { 056 BeanSet<T> beanSet = new BeanSet<>(loader, ownerBean, propertyName); 057 if (many != null) { 058 beanSet.setModifyListening(many.getModifyListenMode()); 059 } 060 return beanSet; 061 } 062 063 @Override 064 public BeanCollection<T> createReference(EntityBean parentBean) { 065 066 BeanSet<T> beanSet = new BeanSet<>(loader, parentBean, propertyName); 067 beanSet.setModifyListening(many.getModifyListenMode()); 068 return beanSet; 069 } 070 071 @Override 072 public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) { 073 074 BeanSet<?> newBeanSet = (BeanSet<?>) server.findSet(query, t); 075 refresh(newBeanSet, parentBean); 076 } 077 078 @Override 079 public void refresh(BeanCollection<?> bc, EntityBean parentBean) { 080 081 BeanSet<?> newBeanSet = (BeanSet<?>) bc; 082 083 Set<?> current = (Set<?>) many.getValue(parentBean); 084 085 newBeanSet.setModifyListening(many.getModifyListenMode()); 086 if (current == null) { 087 // the currentList is null? Not really expecting this... 088 many.setValue(parentBean, newBeanSet); 089 090 } else if (current instanceof BeanSet<?>) { 091 // normally this case, replace just the underlying list 092 BeanSet<?> currentBeanSet = (BeanSet<?>) current; 093 currentBeanSet.setActualSet(newBeanSet.getActualSet()); 094 currentBeanSet.setModifyListening(many.getModifyListenMode()); 095 096 } else { 097 // replace the entire set 098 many.setValue(parentBean, newBeanSet); 099 } 100 } 101 102 @Override 103 public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException { 104 105 Set<?> set; 106 if (collection instanceof BeanCollection<?>) { 107 BeanSet<?> bc = (BeanSet<?>) collection; 108 if (!bc.isPopulated()) { 109 if (explicitInclude) { 110 // invoke lazy loading as collection 111 // is explicitly included in the output 112 bc.size(); 113 } else { 114 return; 115 } 116 } 117 set = bc.getActualSet(); 118 } else { 119 set = (Set<?>) collection; 120 } 121 jsonWriteCollection(ctx, name, set); 122 } 123}