From commits-return-9029-apmail-openjpa-commits-archive=openjpa.apache.org@openjpa.apache.org Fri Aug 26 16:54:32 2011 Return-Path: X-Original-To: apmail-openjpa-commits-archive@www.apache.org Delivered-To: apmail-openjpa-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9342E8B8E for ; Fri, 26 Aug 2011 16:54:32 +0000 (UTC) Received: (qmail 43926 invoked by uid 500); 26 Aug 2011 16:54:32 -0000 Delivered-To: apmail-openjpa-commits-archive@openjpa.apache.org Received: (qmail 43775 invoked by uid 500); 26 Aug 2011 16:54:31 -0000 Mailing-List: contact commits-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list commits@openjpa.apache.org Received: (qmail 43382 invoked by uid 99); 26 Aug 2011 16:54:30 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Aug 2011 16:54:30 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Aug 2011 16:54:26 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C5BB923889DE for ; Fri, 26 Aug 2011 16:54:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1162163 - in /openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel: AbstractBrokerFactory.java AuditManager.java Date: Fri, 26 Aug 2011 16:54:04 -0000 To: commits@openjpa.apache.org From: ppoddar@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110826165404.C5BB923889DE@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: ppoddar Date: Fri Aug 26 16:54:04 2011 New Revision: 1162163 URL: http://svn.apache.org/viewvc?rev=1162163&view=rev Log: OPENJPA-2030: Refactor AuditManager Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AuditManager.java Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java?rev=1162163&r1=1162162&r2=1162163&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java Fri Aug 26 16:54:04 2011 @@ -853,10 +853,7 @@ public abstract class AbstractBrokerFact public void postCreationCallback() { Auditor auditor = _conf.getAuditorInstance(); if (auditor != null) { - AuditManager auditManager = new AuditManager(); - auditManager.setAuditor(auditor); - addLifecycleListener(auditManager, null); - addTransactionListener(auditManager); + addTransactionListener(new AuditManager(auditor)); } if (_conf.isInitializeEagerly()) { newBroker(_conf.getConnectionUserName(), _conf.getConnectionPassword(), Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AuditManager.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AuditManager.java?rev=1162163&r1=1162162&r2=1162163&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AuditManager.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AuditManager.java Fri Aug 26 16:54:04 2011 @@ -52,24 +52,29 @@ import org.apache.openjpa.event.Transact * */ public class AuditManager extends InMemorySavepointManager - implements LifecycleListener, TransactionListener, RegisterClassListener { + implements TransactionListener, RegisterClassListener { - private Auditor _auditor; + private final Auditor _auditor; private final Set> _allTypes; private final Set> _newTypes; private final Set> _updateTypes; private final Set> _deleteTypes; - private final Map> _saved; + private final Map _saved; private final ReentrantLock _lock = new ReentrantLock(); - public AuditManager() { + public AuditManager(Auditor auditor) { super(); + if (auditor == null) { + throw new NullPointerException("null auditor"); + } + setPreFlush(false); + _auditor = auditor; _allTypes = new HashSet>(); _newTypes = new HashSet>(); _updateTypes = new HashSet>(); _deleteTypes = new HashSet>(); - _saved = new ConcurrentHashMap>(); + _saved = new ConcurrentHashMap(); PCRegistry.addRegisterClassListener(this); } @@ -98,10 +103,6 @@ public class AuditManager extends InMemo } } - public void setAuditor(Auditor auditor) { - _auditor = auditor; - } - public Auditor getAuditor() { return _auditor; } @@ -110,46 +111,32 @@ public class AuditManager extends InMemo return Collections.unmodifiableSet(_allTypes); } - /** - * Transaction callbacks. - */ + /** + * ----------------------------------------------------------------------- + * Transaction callbacks. + * ----------------------------------------------------------------------- + */ + @Override - public void beforeCommit(TransactionEvent event) { - if (_auditor == null) return; + public void afterBegin(TransactionEvent event) { _lock.lock(); try { Broker broker = (Broker)event.getSource(); - Set audits = _saved.get(broker); - if (audits == null) return; - Collection news = new HashSet(); - Collection updates = new HashSet(); - Collection deletes = new HashSet(); - Collection instances = event.getTransactionalObjects(); - for (Object instance : instances) { - StateManagerImpl sm = getImpl(instance); - if (sm != null) { - Audited audited = search(audits, sm); - if (audited == null) { - continue; - } - - if (sm.getPCState().isNew()) { - news.add(audited); - } else if (sm.getPCState().isDeleted()) { - deletes.add(audited); - } else if (sm.getPCState().isDirty()) { - updates.add(audited); - } - } - } - try { - _auditor.audit(broker, news, updates, deletes); - } catch (Exception e) { - if (_auditor.isRollbackOnError()) { - throw new RuntimeException("dump", e); - } else { - e.printStackTrace(); - } + AuditCallback cb = new AuditCallback(broker); + broker.addLifecycleListener(cb, _allTypes.toArray(new Class[_allTypes.size()])); + _saved.put(broker, cb); + } finally { + _lock.unlock(); + } + } + + @Override + public void beforeCommit(TransactionEvent event) { + _lock.lock(); + try { + AuditCallback cb = _saved.get(event.getSource()); + if (cb != null) { + cb.audit(); } } finally { _lock.unlock(); @@ -167,110 +154,28 @@ public class AuditManager extends InMemo } @Override - public void afterBegin(TransactionEvent event) { - } - - @Override - public void beforeFlush(TransactionEvent event) { - } - - @Override - public void afterFlush(TransactionEvent event) { - } - - @Override - public void afterStateTransitions(TransactionEvent event) { - } - - @Override public void afterCommitComplete(TransactionEvent event) { + _saved.remove(event.getSource()); } @Override public void afterRollbackComplete(TransactionEvent event) { + _saved.remove(event.getSource()); } - - /** - * Life-cycle callbacks - */ - @Override - public void afterLoad(LifecycleEvent event) { - save(AuditableOperation.ALL, event); - } - - @Override - public void afterPersist(LifecycleEvent event) { - save(AuditableOperation.CREATE, event); - } - - @Override - public void beforeDelete(LifecycleEvent event) { - save(AuditableOperation.DELETE, event); - } - - @Override - public void beforeDirty(LifecycleEvent event) { - if (!isAudited(event)) { - save(AuditableOperation.UPDATE, event); - } - } - - @Override - public void beforePersist(LifecycleEvent event) { - } - - @Override - public void afterRefresh(LifecycleEvent event) { - } - - @Override - public void beforeStore(LifecycleEvent event) { - } - - @Override - public void afterStore(LifecycleEvent event) { - } - - @Override - public void beforeClear(LifecycleEvent event) { - } - - @Override - public void afterClear(LifecycleEvent event) { - } - - @Override - public void afterDelete(LifecycleEvent event) { - } - - @Override - public void afterDirty(LifecycleEvent event) { - } - - @Override - public void beforeDirtyFlushed(LifecycleEvent event) { - } - + @Override - public void afterDirtyFlushed(LifecycleEvent event) { + public void beforeFlush(TransactionEvent event) { } @Override - public void beforeDetach(LifecycleEvent event) { + public void afterFlush(TransactionEvent event) { } @Override - public void afterDetach(LifecycleEvent event) { + public void afterStateTransitions(TransactionEvent event) { } - @Override - public void beforeAttach(LifecycleEvent event) { - } - @Override - public void afterAttach(LifecycleEvent event) { - } - /** * Support functions. */ @@ -285,17 +190,6 @@ public class AuditManager extends InMemo } /** - * Affirms if source of the given event is being audited already. - */ - protected boolean isAudited(LifecycleEvent event) { - StateManagerImpl sm = getImpl(event.getSource()); - if (_saved.containsKey(sm.getBroker())) { - return search(_saved.get(sm.getBroker()), sm) != null; - } - return false; - } - - /** * Extracts the broker from the given persistence capable instance. * @param pc a persistence capable instance * @return null if a Broker can notbe extracted @@ -307,47 +201,6 @@ public class AuditManager extends InMemo } /** - * Saves the source of the given event for auditing. - * @param lc - * @param event - */ - protected void save(AuditableOperation lc, LifecycleEvent event) { - StateManagerImpl sm = getImpl(event.getSource()); - if (sm != null && isAuditable(lc, sm)) { - Broker broker = sm.getBroker(); - - OpenJPASavepoint savepoint = newSavepoint("", broker); - savepoint.save(Collections.singleton(sm)); - Map states = savepoint.getStates(); - Map.Entry e = states.entrySet().iterator().next(); - PersistenceCapable copy = e.getValue().getCopy(); - copy.pcReplaceStateManager(null); - Audited audited = new Audited(sm, copy); - Set audits = _saved.get(broker); - if (audits == null) { - audits = new HashSet(); - _saved.put(broker, audits); - } - audits.add(audited); - } - } - - /** - * Searches the set of Auditable instances for a matching Statemanager. - * @param audits - * @param sm - * @return - */ - private Audited search(Set audits, StateManagerImpl sm) { - for (Audited audit : audits) { - if (audit.getManagedObject() == sm.getPersistenceCapable()) { - return audit; - } - } - return null; - } - - /** * Gets an implementation. * @param instance * @return @@ -381,5 +234,144 @@ public class AuditManager extends InMemo ||(op == AuditableOperation.DELETE && _deleteTypes.contains(cls)); } + /** + * Listens to entity life cycle operations and saves them for auditing. + * + */ + private class AuditCallback implements LifecycleListener { + private final Broker _broker; + private final Map _audits = + new ConcurrentHashMap(); + + AuditCallback(Broker broker) { + _broker = broker; + } + void audit() { + if (_audits.isEmpty()) return; + Collection news = new HashSet(); + Collection updates = new HashSet(); + Collection deletes = new HashSet(); + for (Map.Entry e : _audits.entrySet()) { + StateManagerImpl sm = e.getKey(); + Audited audited = new Audited(sm, e.getValue()); + if (sm.getPCState().isNew()) { + news.add(audited); + } else if (sm.getPCState().isDeleted()) { + deletes.add(audited); + } else if (sm.getPCState().isDirty()) { + updates.add(audited); + } + } + try { + _auditor.audit(_broker, news, updates, deletes); + } catch (Exception e) { + if (_auditor.isRollbackOnError()) { + throw new RuntimeException("dump", e); + } else { + e.printStackTrace(); + } + } + } + + /** + * Saves the source of the given event for auditing. + * @param op an auditable operation + * @param event the event + */ + protected void save(AuditableOperation op, LifecycleEvent event) { + StateManagerImpl sm = getImpl(event.getSource()); + if (sm != null && !_audits.containsKey(sm) && isAuditable(op, sm)) { + Broker broker = sm.getBroker(); + + OpenJPASavepoint savepoint = newSavepoint("", broker); + savepoint.save(Collections.singleton(sm)); + Map states = savepoint.getStates(); + Map.Entry e = states.entrySet().iterator().next(); + PersistenceCapable copy = e.getValue().getCopy(); + copy.pcReplaceStateManager(null); + _audits.put(sm, copy); + } + } + + /** + * Life-cycle callbacks + */ + @Override + public void afterLoad(LifecycleEvent event) { + save(AuditableOperation.ALL, event); + } + + @Override + public void afterPersist(LifecycleEvent event) { + save(AuditableOperation.CREATE, event); + } + + @Override + public void beforeDelete(LifecycleEvent event) { + save(AuditableOperation.DELETE, event); + } + + @Override + public void beforeDirty(LifecycleEvent event) { + save(AuditableOperation.UPDATE, event); + } + + @Override + public void beforePersist(LifecycleEvent event) { + } + + @Override + public void afterRefresh(LifecycleEvent event) { + } + + @Override + public void beforeStore(LifecycleEvent event) { + } + + @Override + public void afterStore(LifecycleEvent event) { + } + + @Override + public void beforeClear(LifecycleEvent event) { + } + + @Override + public void afterClear(LifecycleEvent event) { + } + + @Override + public void afterDelete(LifecycleEvent event) { + } + + @Override + public void afterDirty(LifecycleEvent event) { + } + + @Override + public void beforeDirtyFlushed(LifecycleEvent event) { + } + + @Override + public void afterDirtyFlushed(LifecycleEvent event) { + } + + @Override + public void beforeDetach(LifecycleEvent event) { + } + + @Override + public void afterDetach(LifecycleEvent event) { + } + + @Override + public void beforeAttach(LifecycleEvent event) { + } + + @Override + public void afterAttach(LifecycleEvent event) { + } + + } }