001package com.avaje.ebean.bean; 002 003import java.io.Serializable; 004import java.util.Collection; 005import java.util.Set; 006 007import com.avaje.ebean.ExpressionList; 008 009/** 010 * Lazy loading capable Maps, Lists and Sets. 011 * <p> 012 * This also includes the ability to listen for additions and removals to or 013 * from the Map Set or List. The purpose of gathering the additions and removals 014 * is to support persisting ManyToMany objects. The additions and removals 015 * become inserts and deletes from the intersection table. 016 * </p> 017 * <p> 018 * Technically this is <em>NOT</em> an extension of 019 * <em>java.util.Collection</em>. The reason being that java.util.Map is not a 020 * Collection. I realise this makes this name confusing so I apologise for that. 021 * </p> 022 */ 023public interface BeanCollection<E> extends Serializable { 024 025 enum ModifyListenMode { 026 /** The common mode */ 027 NONE, 028 /** Mode used for PrivateOwned */ 029 REMOVALS, 030 /** Mode used for ManyToMany relationships */ 031 ALL 032 } 033 034 /** 035 * Add a bean to the list/set with modifyListen notification. 036 */ 037 void addBean(E bean); 038 039 /** 040 * Remove a bean to the list/set with modifyListen notification. 041 */ 042 void removeBean(E bean); 043 044 /** 045 * Reset the collection back to an empty state ready for reloading. 046 * <p> 047 * This is done as part of bean refresh. 048 */ 049 void reset(EntityBean ownerBean, String propertyName); 050 051 /** 052 * Return true if the collection is empty and untouched. Used to detect if a 053 * collection was 'cleared' deliberately or just un-initialised. 054 */ 055 boolean isEmptyAndUntouched(); 056 057 /** 058 * Return the bean that owns this collection. 059 */ 060 EntityBean getOwnerBean(); 061 062 /** 063 * Return the bean property name this collection represents. 064 */ 065 String getPropertyName(); 066 067 /** 068 * Check after the lazy load that the underlying collection is not null 069 * (handle case where join to many not outer). 070 * <p> 071 * That is, if the collection was not loaded due to filterMany predicates etc 072 * then make sure the collection is set to empty. 073 * </p> 074 */ 075 boolean checkEmptyLazyLoad(); 076 077 /** 078 * Return the filter (if any) that was used in building this collection. 079 * <p> 080 * This is so that the filter can be applied on refresh. 081 * </p> 082 */ 083 ExpressionList<?> getFilterMany(); 084 085 /** 086 * Set the filter that was used in building this collection. 087 */ 088 void setFilterMany(ExpressionList<?> filterMany); 089 090 /** 091 * Set a listener to be notified when the BeanCollection is first touched. 092 */ 093 void setBeanCollectionTouched(BeanCollectionTouched notify); 094 095 /** 096 * Return true if the collection has been registered with the batch loading context. 097 */ 098 boolean isRegisteredWithLoadContext(); 099 100 /** 101 * Set the loader that will be used to lazy/query load this collection. 102 * <p> 103 * This is effectively the batch loading context this collection is registered with. 104 * </p> 105 */ 106 void setLoader(BeanCollectionLoader beanLoader); 107 108 /** 109 * Set to true if you want the BeanCollection to be treated as read only. This 110 * means no elements can be added or removed etc. 111 */ 112 void setReadOnly(boolean readOnly); 113 114 /** 115 * Return true if the collection should be treated as readOnly and no elements 116 * can be added or removed etc. 117 */ 118 boolean isReadOnly(); 119 120 /** 121 * Add the bean to the collection. 122 * <p> 123 * This is disallowed for BeanMap. 124 * </p> 125 */ 126 void internalAdd(Object bean); 127 128 /** 129 * Add the bean with a check to see if it is already contained. 130 */ 131 void internalAddWithCheck(Object bean); 132 133 /** 134 * Return the number of elements in the List Set or Map. 135 */ 136 int size(); 137 138 /** 139 * Return true if the List Set or Map is empty. 140 */ 141 boolean isEmpty(); 142 143 /** 144 * Returns the underlying collection of beans from the Set, Map or List. 145 */ 146 Collection<E> getActualDetails(); 147 148 /** 149 * Returns the underlying entries so for Maps this is a collection of 150 * Map.Entry. 151 * <p> 152 * For maps this returns the entrySet as we need the keys of the map. 153 * </p> 154 */ 155 Collection<?> getActualEntries(); 156 157 /** 158 * return true if there are real rows held. Return false is this is using 159 * Deferred fetch to lazy load the rows and the rows have not yet been 160 * fetched. 161 */ 162 boolean isPopulated(); 163 164 /** 165 * Return true if this is a reference (lazy loading) bean collection. This is 166 * the same as !isPopulated(); 167 */ 168 boolean isReference(); 169 170 /** 171 * Set modify listening on or off. This is used to keep track of objects that 172 * have been added to or removed from the list set or map. 173 * <p> 174 * This is required only for ManyToMany collections. The additions and 175 * deletions are used to insert or delete entries from the intersection table. 176 * Otherwise modifyListening is false. 177 * </p> 178 */ 179 void setModifyListening(ModifyListenMode modifyListenMode); 180 181 /** 182 * Add an object to the additions list. 183 * <p> 184 * This will potentially end up as an insert into a intersection table for a 185 * ManyToMany. 186 * </p> 187 */ 188 void modifyAddition(E bean); 189 190 /** 191 * Add an object to the deletions list. 192 * <p> 193 * This will potentially end up as an delete from an intersection table for a 194 * ManyToMany. 195 * </p> 196 */ 197 void modifyRemoval(Object bean); 198 199 /** 200 * Return the list of objects added to the list set or map. These will used to 201 * insert rows into the intersection table of a ManyToMany. 202 */ 203 Set<E> getModifyAdditions(); 204 205 /** 206 * Return the list of objects removed from the list set or map. These will 207 * used to delete rows from the intersection table of a ManyToMany. 208 */ 209 Set<E> getModifyRemovals(); 210 211 /** 212 * Reset the set of additions and deletions. This is called after the 213 * additions and removals have been processed. 214 */ 215 void modifyReset(); 216}