001    package data;
002    
003    import java.util.Iterator;
004    import java.util.Set;
005    
006    import data.events.VetoException;
007    
008    /**
009     * A Catalog.
010     *
011     * <p>Catalogs are - usually system global - lists of items. Each Catalog has a name unique to its scope of
012     * usage. It is identified by this name. Catalogs consist of {@link CatalogItem CatalogItems}, which comprise
013     * a key ({@link String}), possibly a value ({@link Value}) and any number of additional attributes as needed
014     * to correctly describe the item.</p>
015     *
016     * <p>A Catalog is capable to test whether it contains CatalogItems with a certain key or matching a given
017     * CatalogItem. It will make available for editing the CatalogItem of a given key, if this key is contained
018     * in the Catalog.</p>
019     *
020     * <p>Catalogs support the usage of {@link DataBasket DataBaskets} so that all operations on the Catalog can
021     * be performed in a transactional style.</p>
022     *
023     * <p>As a Catalog is itself a CatalogItem, constructing arbitrarily nested Catalogs is possible.</p>
024     *
025     * <p>A Catalog is serializable to allow for it to be stored to an ObjectOutputStream.</p>
026     *
027     * @see Stock
028     *
029     * @author Steffen Zschaler
030     * @version 2.0 18/08/1999
031     * @since v0.5
032     */
033    public interface Catalog extends CatalogItem, DataBasketEntrySource, DataBasketEntryDestination {
034    
035        /**
036         * Add a CatalogItem to the Catalog.
037         *
038         * <p>The added item will only be visible to users of the same DataBasket. Only after a
039         * {@link DataBasket#commit() commit()} was executed on the DataBasket, the added item will become visible
040         * to other users of the Catalog.</p>
041         *
042         * <p>For a {@link ListenableCatalog}, a <code>addedCatalogItem</code> event will be fired.</p>
043         *
044         * @override Always
045         *
046         * @param ci the CatalogItem to be added. This item must not be contained in another Catalog.
047         * @param db the DataBasket relative to which the operation is to be performed.
048         *
049         * @exception NotEditableException if the Catalog is currently not editable.
050         * @exception DuplicateKeyException if a CatalogItem of the same name does already exist in the Catalog.
051         * @exception DataBasketConflictException if the CatalogItem cannot be added because an item of the same
052         * name has already been added/removed using another DataBasket.
053         */
054        public void add(CatalogItem ci, DataBasket db);
055    
056        /**
057         * Remove a CatalogItem from the Catalog.
058         *
059         * <p>The item's removal will be immediately visible to all users of the Catalog. However, only users of the
060         * same DataBasket that was used to remove the item will be able to add an item with the same key later.
061         * Only after a {@link DataBasket#commit() commit()} was executed on the DataBasket, other users of the
062         * Catalog will have a chance to add an item with the same key.</p>
063         *
064         * <p>For a {@link ListenableCatalog}, <code>canRemoveCatalogItem</code> and
065         * <code>removedCatalogItem</code> events will be fired. If one of the listeners vetos the removal, a
066         * {@link data.events.VetoException} will be thrown.</p>
067         *
068         * @override Always
069         *
070         * @param ci the CatalogItem to be removed.
071         * @param db the DataBasket relative to which the operation is to be performed.
072         *
073         * @return the item that was actually removed.
074         *
075         * @exception NotEditableException if the Catalog is currently not editable.
076         * @exception VetoException if one of the listeners vetos the removal.
077         * @exception DataBasketConflictException if the CatalogItem cannot be removed because an item of the same
078         * name has already been added using another DataBasket.
079         */
080        public CatalogItem remove(CatalogItem ci, DataBasket db) throws VetoException;
081    
082        /**
083         * Remove a CatalogItem from the Catalog.
084         *
085         * <p>The item's removal will be immediately visible to all users of the Catalog. However, only users of the
086         * same DataBasket that was used to remove the item will be able to add an item with the same key later.
087         * Only after a {@link DataBasket#commit() commit()} was executed on the DataBasket, other users of the
088         * Catalog will have a chance to add an item with the same key.</p>
089         *
090         * <p>For a {@link ListenableCatalog}, <code>canRemoveCatalogItem</code> and
091         * <code>removedCatalogItem</code> events will be fired. If one of the listeners vetos the removal, a
092         * {@link data.events.VetoException} will be thrown.</p>
093         *
094         * @override Always
095         *
096         * @param sKey the key of the CatalogItem to be removed.
097         * @param db the DataBasket relative to which the operation is to be performed.
098         *
099         * @return the item that was actually removed.
100         *
101         * @exception NotEditableException if the Catalog is currently not editable.
102         * @exception VetoException if one of the listeners vetos the removal.
103         * @exception DataBasketConflictException if the CatalogItem cannot be removed because an item of the same
104         * name has already been added using another DataBasket.
105         */
106        public CatalogItem remove(String sKey, DataBasket db) throws VetoException;
107    
108        /**
109         * Get a CatalogItem by its key.
110         *
111         * <p>There are two distinct possibilities when getting a CatalogItem from a Catalog:</p>
112         *
113         * <ol>
114         *   <li><b>Just for looking at it</b> <i>(<code>fForEdit</code> == false)</i>:<br>
115         *       In this case the original item is delivered if it is visible for users of the given DataBasket.
116         *       However, no guarantee is given that the item will still be in the Catalog the next time you look.
117         *       Also, editing the retrieved item is illegal and may result in corrupted data.
118         *   </li>
119         *   <li><b>For editing</b> <i>(<code>fForEdit</code> == true)</i>:<br>
120         *       In this case, the item is specially prepared for editing before delivering it. The item will no
121         *       longer be visible to users of other DataBaskets until a {@link DataBasket#commit()} is performed
122         *       on the DataBasket. It is legal to edit the retrieved item (however, not necessarily the same item
123         *       that was retrieved earlier using possibility 1 !!!), and all editing can be commited or rolled back
124         *       using the DataBasket. This possibility can, however, be vetoed if this is a
125         *       {@link ListenableCatalog}.<br><br>
126         *       For a {@link ListenableCatalog}, <code>canEditCatalogItem</code> and
127         *       <code>editingCatalogItem</code> events will be fired. If one of the listeners vetos the editing, a
128         *       {@link data.events.VetoException} will be thrown.
129         *   </li>
130         * </ol>
131         *
132         * <p> </p>
133         *
134         * @override Always
135         *
136         * @param sKey the key of the CatalogItem to be retrieved.
137         * @param db the DataBasket relative to which the operation is to be performed.
138         * @param fForEdit if true, the CatalogItem will be retrieved for editing.
139         *
140         * @return the item that is associated with the given key.
141         *
142         * @exception NotEditableException if the Catalog is not currently editable, but an attempt is made to edit
143         * one of its items.
144         * @exception VetoException if one of the listeners vetos the editing.
145         * @exception DataBasketConflictException if the CatalogItem cannot be retrieved because it is not visible
146         * to users of the given DataBasket.
147         */
148        public CatalogItem get(String sKey, DataBasket db, boolean fForEdit) throws VetoException;
149    
150        /**
151         * Check whether the Catalog contains a certain CatalogItem.
152         *
153         * <p>Will return true only if an item of the given key is contained in the Catalog and if that item is
154         * visible to users of the given DataBasket.</p>
155         *
156         * @override Always
157         *
158         * @param sKey the key for which to check containment.
159         * @param db the DataBasket that defines visibility of items. See {@link #add} and {@link #remove} for
160         * details on visibility.
161         */
162        public boolean contains(String sKey, DataBasket db);
163    
164        /**
165         * Return an iterator of all items in the Catalog.
166         *
167         * <p>The iterator will conceptually call {@link #get} for each CatalogItem, using the given parameters.
168         *
169         * @override Always
170         *
171         * @param db the DataBasket that defines visibility.
172         * @param fForEdit if true, the items are retrieved for editing. VetoException will be converted into
173         * <code>UnsupportedOperationException</code>s.
174         */
175        public Iterator iterator(DataBasket db, boolean fForEdit);
176    
177        /**
178         * Get a set of all keys currently in the Catalog.
179         *
180         * <p>This will retrieve a static set that gives the state of the Catalog at the time of the call.</p>
181         *
182         * @param db the DataBasket used to determine visibility of elements.
183         *
184         * @override Always
185         */
186        public Set keySet(DataBasket db);
187    
188        /**
189         * Calculate the size of the Catalog. I.e. count the CatalogItems that are visible to users of the given DataBasket.
190         *
191         * @override Always
192         *
193         * @param db the DataBasket used to determine visibility.
194         */
195        public int size(DataBasket db);
196    }