001    package org.apache.ojb.broker;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
019    import org.apache.ojb.broker.accesslayer.JdbcAccess;
020    import org.apache.ojb.broker.accesslayer.StatementManagerIF;
021    import org.apache.ojb.broker.accesslayer.sql.SqlGenerator;
022    import org.apache.ojb.broker.cache.ObjectCache;
023    import org.apache.ojb.broker.metadata.ClassDescriptor;
024    import org.apache.ojb.broker.metadata.DescriptorRepository;
025    import org.apache.ojb.broker.query.Query;
026    import org.apache.ojb.broker.util.BrokerHelper;
027    import org.apache.ojb.broker.util.ObjectModification;
028    import org.apache.ojb.broker.util.configuration.Configurable;
029    import org.apache.ojb.broker.util.sequence.SequenceManager;
030    import org.odbms.ObjectContainer;
031    
032    import java.util.Collection;
033    import java.util.Enumeration;
034    import java.util.Iterator;
035    
036    /**
037     *
038     * PersistenceBroker declares a protocol for persisting arbitrary objects.
039     * A typical implementation might wrap an RDBMS access layer.
040     *
041     * @see org.apache.ojb.broker.core.PersistenceBrokerImpl
042     * @see org.apache.ojb.broker.core.PersistenceBrokerBean
043     *
044     * @author Thomas Mahler
045     * @version $Id: PersistenceBroker.java,v 1.1 2007-08-24 22:17:35 ewestfal Exp $
046     */
047    public interface PersistenceBroker extends Configurable, ObjectContainer
048    {
049        // *************************************************************************
050        // Services handled by the PersistenceBroker
051        // *************************************************************************
052    
053        /**
054         * Returns the {@link org.apache.ojb.broker.accesslayer.StatementManagerIF} instance associated with this broker.
055         * 
056         * @return The statement manager
057         */
058        public StatementManagerIF serviceStatementManager();
059    
060        /**
061         * Returns the {@link org.apache.ojb.broker.accesslayer.ConnectionManagerIF} instance associated with this broker.
062         * 
063         * @return The connection manager
064         */
065        public ConnectionManagerIF serviceConnectionManager();
066    
067        /**
068         * Returns the {@link org.apache.ojb.broker.accesslayer.sql.SqlGenerator} instance associated with this broker.
069         * 
070         * @return The SQL generator
071         */
072        public SqlGenerator serviceSqlGenerator();
073    
074        /**
075         * Returns the {@link org.apache.ojb.broker.accesslayer.JdbcAccess} instance associated with this broker.
076         * 
077         * @return The JDBC access object
078         */
079        public JdbcAccess serviceJdbcAccess();
080    
081        /**
082         * Returns the {@link org.apache.ojb.broker.util.sequence.SequenceManager} instance associated with this broker.
083         * 
084         * @return The sequence manager
085         */
086        public SequenceManager serviceSequenceManager();
087    
088        /**
089         * Returns the {@link org.apache.ojb.broker.util.BrokerHelper} instance associated with this broker, which
090         * makes some additional helper methods available.
091         * 
092         * @return The broker helper object
093         */
094        public BrokerHelper serviceBrokerHelper();
095    
096        /**
097         * Returns the {@link org.apache.ojb.broker.cache.ObjectCache} instance associated
098         * with this broker.
099         * 
100         * @return The object cache
101         */
102        public ObjectCache serviceObjectCache();
103    
104        /**
105         * Return the {@link IdentityFactory} instance associated with this broker.
106         * 
107         * @return The identity factory
108         */
109        public IdentityFactory serviceIdentity();
110    
111    
112        // *************************************************************************
113        // PersistenceBroker listener methods
114        // *************************************************************************
115    
116        /**
117         * Fires a broker event to inform all registered {@link PBListener} instances.
118         * 
119         * @param event The event to fire
120         */
121        public void fireBrokerEvent(PersistenceBrokerEvent event);
122    
123        /**
124         * Fires a life cycle event to inform all registered {@link PBListener} instances.
125         * 
126         * @param event The event to fire
127         */
128        public void fireBrokerEvent(PBLifeCycleEvent event);
129    
130        /**
131         * Fires a state event to inform all registered {@link PBListener} instances.
132         * 
133         * @param event The event to fire
134         */
135        public void fireBrokerEvent(PBStateEvent event);
136    
137        /**
138         * Removes all temporary listeners from this broker.
139         * Use with care, because some internals rely on this mechanism.
140         * 
141         * @see #removeListener(PBListener)
142         */
143        public void removeAllListeners() throws PersistenceBrokerException;
144    
145        /**
146         * Removes all temporary and, if desired, permanent listeners from this broker.
147         * Use with care, because some internals rely on this mechanism.
148         * 
149         * @param permanent Whether the listener will stay registered after closing
150         *                  the broker
151         * @see #removeListener(PBListener)
152         */
153        public void removeAllListeners(boolean permanent) throws PersistenceBrokerException;
154    
155    
156        /**
157         * Adds a temporary {@link org.apache.ojb.broker.PBListener} to this broker.
158         * Note that temporary listeners will be removed upon closing a broker (returning
159         * it to the pool).
160         *
161         * @param listener The listener to add
162         * @see #addListener(PBListener, boolean)
163         */
164        public void addListener(PBListener listener) throws PersistenceBrokerException;
165    
166        /**
167         * Adds a temporary or permanent {@link org.apache.ojb.broker.PBListener} to this broker,
168         * depending on the parameter value. Note that temporary listeners will be removed upon
169         * closing a broker (returning it to the pool).
170         * <br/>
171         * <b>NOTE:</b> Handle carefully when using this method, keep in mind you don't
172         * know which broker instance will be returned next time from the pool! To guarantee that
173         * a listener is connect to every broker, the best way is to define your own implementation of
174         * {@link org.apache.ojb.broker.core.PersistenceBrokerFactoryIF} or extend the default
175         * one, {@link org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl}. There you
176         * can add the listener at creation of the {@link org.apache.ojb.broker.PersistenceBroker}
177         * instances.
178         * 
179         * @param listener  The listener to add
180         * @param permanent Whether the listener will stay registered after closing
181         *                  the broker
182         */
183        public void addListener(PBListener listener, boolean permanent) throws PersistenceBrokerException;
184    
185        /**
186         * Removes the specified listener from this broker.
187         * 
188         * @param listener The listener to remove
189         */
190        public void removeListener(PBListener listener) throws PersistenceBrokerException;
191    
192    
193        // *************************************************************************
194        // Transaction and instance handling stuff
195        // *************************************************************************
196    
197        /**
198         * Aborts and closes the current transaction. This abandons all persistent object modifications
199         * and releases the associated locks.
200         * 
201         * @throws TransactionNotInProgressException If no transaction is currently in progress
202         */
203        public void abortTransaction() throws TransactionNotInProgressException;
204    
205        /**
206         * Begins a transaction against the underlying RDBMS.
207         * 
208         * @throws TransactionInProgressException If there is already a transaction in progress
209         */
210        public void beginTransaction() throws TransactionInProgressException, TransactionAbortedException;
211    
212        /**
213         * Commits and closes the current transaction. This commits all database-changing statements (e.g.
214         * UPDATE, INSERT and DELETE) issued within the transaction since the last commit to the database,
215         * and releases any locks held by the transaction.
216         * 
217         * @throws TransactionNotInProgressException If there is no transaction currently in progress
218         * @throws TransactionAbortedException       If the transaction cannot be committed
219         */
220        public void commitTransaction() throws TransactionNotInProgressException, TransactionAbortedException;
221    
222        /**
223         * Determines whether there is currently a transaction in progress.
224         * 
225         * @return <code>true</code> if there is a transaction in progress
226         */
227        public boolean isInTransaction() throws PersistenceBrokerException;
228    
229        /**
230         * Closes this broker so that no further requests may be made on it. Closing a broker might release
231         * it to the pool of available brokers, or might be garbage collected, at the option of the implementation.
232         *
233         * @return <code>true</code> if the broker was successfully closed
234         */
235        public boolean close();
236    
237        /**
238         * Determines whether this broker is closed.
239         * 
240         * @return <tt>true</tt> if this instance is closed
241         */
242        public boolean isClosed();
243    
244    
245    
246        // *************************************************************************
247        // Metadata service methods
248        // *************************************************************************
249    
250        /**
251         * Returns the metadata descriptor repository associated with this broker.
252         * 
253         * @return The descriptor repository
254         */
255        public DescriptorRepository getDescriptorRepository();
256    
257        /**
258         * Get the {@link PBKey} for this broker.
259         * 
260         * @return The broker key
261         */
262        public PBKey getPBKey();
263    
264        /**
265         * Returns the class descriptor for the given persistence capable class.
266         * 
267         * @param clazz The target class
268         * @return The class descriptor
269         * @throws PersistenceBrokerException If the class is not persistence capable, i.e.
270         *         if no metadata was defined for this class and hence its class descriptor
271         *         was not found
272         */
273        public ClassDescriptor getClassDescriptor(Class clazz) throws PersistenceBrokerException;
274    
275        /**
276         * Determines whether the given class is persistence capable and thus has an associated
277         * class descriptor in the metadata.
278         * 
279         * @param clazz The target class
280         * @return <code>true</code> if a class descriptor was found
281         */
282        public boolean hasClassDescriptor(Class clazz);
283    
284        /**
285         * Returns the top level class (most abstract class in terms of extents) from which the
286         * given class extends. This may be a (abstract) base-class, an interface or the given
287         * class itself, if no extent is defined.
288         *
289         * @param clazz The class to get the top level class for
290         * @return The top level class for it
291         * @throws PersistenceBrokerException If the class is not persistence capable,
292         *         if no metadata was defined for this class
293         */
294        public Class getTopLevelClass(Class clazz) throws PersistenceBrokerException;
295    
296        // *************************************************************************
297        // Object lifecycle
298        // *************************************************************************
299    
300        /**
301         * Clears the broker's internal cache.
302         */
303        public void clearCache() throws PersistenceBrokerException;
304    
305        /**
306         * Removes the given object or, if it is an instance of {@link org.apache.ojb.broker.Identity},
307         * the object identified by it, from the broker's internal cache. Note that the removal is
308         * not recursive. This means, objects referenced by the removed object will not be
309         * automatically removed from the cache by this operation.
310         * 
311         * @param objectOrIdentity The object to be removed from the cache or its identity 
312         */
313        public void removeFromCache(Object objectOrIdentity) throws PersistenceBrokerException;
314    
315        /**
316         * Makes the given object persistent in the underlying persistence system.
317         * This is usually done by issuing an INSERT ... or UPDATE ...  in an RDBMS.
318         *
319         * @param obj The object to store
320         * @param modification Specifies what operation to perform (for generating optimized SQL)
321         */
322        public void store(Object obj,
323                          ObjectModification modification) throws PersistenceBrokerException;
324    
325        /**
326         * Make the given object persistent in the underlying persistence system.
327         * This is usually done by issuing an INSERT ... or UPDATE ...  in an RDBMS.
328         * 
329         * @param obj The object to store
330         */
331        public void store(Object obj) throws PersistenceBrokerException;
332    
333        /**
334         * Deletes the given object's persistent representation in the underlying persistence system.
335         * This is usually done by issuing a DELETE ... in an RDBMS
336         * 
337         * @param obj The object to delete
338         */
339        public void delete(Object obj) throws PersistenceBrokerException;
340    
341        /**
342         * Deletes an m:n implementor which defines the relationship between two persistent objects.
343         * This is usually a row in an indirection table.<br/>
344         * Note that OJB currently doesn't handle collection inheritance, so collections descriptors
345         * are written per class. We try to match one of these collection descriptors, iterating from the left side
346         * and looking for possible for classes on the right side using isAssignableFrom(rightClass).
347         *
348         * TODO: handle cache problems
349         * TODO: delete more than one row if possible
350         * 
351         * @param m2nImpl The m:n implementor to delete
352         */
353        public void deleteMtoNImplementor(MtoNImplementor m2nImpl) throws PersistenceBrokerException;
354    
355        /**
356         * Stores the given m:n implementor int the underlying persistence system. 
357         * This is usually done by inserting a row in an indirection table.<br/>
358         * Note that OJB currently doesn't handle collection inheritance, so collections descriptors
359         * are written per class. We try to match one of these collection descriptors, iterating from the left side
360         * and looking for possible for classes on the right side using isAssignableFrom(rightClass).
361         * 
362         * @param m2nImpl The m:n implementor to delete
363         */
364        public void addMtoNImplementor(MtoNImplementor m2nImpl) throws PersistenceBrokerException;
365    
366        /**
367         * Deletes all objects matching the given query, from the underlying persistence system.
368         * This is usually done via DELETE ... in an RDBMS.<br/>
369         * <b>Note:</b> This method directly perform the delete statement ignoring any object
370         * references and does not synchronize the cache - take care!
371         * 
372         * @param query The query determining the objects to delete
373         */
374        public void deleteByQuery(Query query) throws PersistenceBrokerException;
375    
376        // *************************************************************************
377        // Query methods
378        // *************************************************************************
379    
380        /**
381         * Retrieve all references and collections of the given object irrespective of the
382         * metadata settings defined for them.
383         *  
384         * @param obj The persistent object
385         */
386        public void retrieveAllReferences(Object obj) throws PersistenceBrokerException;
387    
388        /**
389         * Retrieve the specified reference or collection attribute for the given persistent object.
390         * 
391         * @param obj      The persistent object
392         * @param attrName The name of the attribute to retrieve
393         */
394        public void retrieveReference(Object obj, String attrName) throws PersistenceBrokerException;
395    
396        /**
397         * Returns the number of elements that the given query will return.
398         * 
399         * @param query The query
400         * @return The number of elements returned by the query
401         */
402        public int getCount(Query query) throws PersistenceBrokerException;
403    
404        /**
405         * Retrieves the persistent objects matching the given query. Note that if the Query has
406         * no criteria ALL persistent objects of the class targeted by the query will be returned.
407         * 
408         * @param query The query
409         * @return The persistent objects matching the query
410         */
411        public Collection getCollectionByQuery(Query query) throws PersistenceBrokerException;
412    
413        /**
414         * Retrieves the persistent objects matching the given query. The resulting collection will
415         * be of the supplied collection type. Note that if the Query has no criteria ALL persistent
416         * objects of the class targeted by the query will be returned.
417         * 
418         * @param collectionClass The collection type which needs to implement
419         *                        {@link ManageableCollection}
420         * @param query           The query
421         * @return The persistent objects matching the query
422         */
423        public ManageableCollection getCollectionByQuery(Class collectionClass, Query query)
424                throws PersistenceBrokerException;
425    
426        /**
427         * Retrieves the persistent objects matching the given query and returns them as an iterator
428         * which may, depending on the configured collection type, be reloading the objects from
429         * the database upon calling {@link Iterator#next()}. Note that if the Query has no criteria
430         * ALL persistent objects of the class targeted by the query will be returned.
431         * 
432         * @param query The query
433         * @return The persistent objects matching the query
434         */
435        public Iterator getIteratorByQuery(Query query) throws PersistenceBrokerException;
436    
437        /**
438         * Retrieves the rows (as <code>Object[]</code> instances) matching the given query and
439         * returns them as an iterator which may, depending on the configured collection type, be reloading
440         * the objects from the database upon calling {@link Iterator#next()}.
441         * 
442         * @param query The report query
443         * @return The rows matching the query
444         */
445        public Iterator getReportQueryIteratorByQuery(Query query) throws PersistenceBrokerException;
446    
447        /**
448         * Retrieve a persistent object from the underlying datastore by its identity. However, users
449         * are encouraged to use {@link #getObjectByQuery(Query)} instead, as this method is mainly
450         * intended to be used for internal handling of materialization by OID (e.g. in Proxies).
451         * 
452         * @param id The persistent object's id
453         * @return The persistent object
454         */
455        public Object getObjectByIdentity(Identity id) throws PersistenceBrokerException;
456    
457        /**
458         * Retrieve the (first) persistent object from the underlying datastore that matches the given
459         * query.
460         * 
461         * @param query The query
462         * @return The persistent object
463         */
464        public Object getObjectByQuery(Query query) throws PersistenceBrokerException;
465    
466        /**
467         * Returns an enumeration of objects representing the primary keys for the objects that match
468         * the given query. Mainly useful for EJB Finder Methods.<br/>
469         * <b>Note:</b> This method is not yet aware of extents!
470         * 
471         * @param pkClass The class to use for the primary keys
472         * @param query   The query
473         * @return The pk enumeration
474         */
475        public Enumeration getPKEnumerationByQuery(Class pkClass, Query query)
476                throws PersistenceBrokerException;
477    }