Bug 291546 - Performance degradation due to usage of Vector in DescriptorEventManager
Signed-off-by: Tomas Kraus <tomas.kraus@oracle.com>
Reviewed-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/AddressDescriptorEventListener.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/AddressDescriptorEventListener.java
index 0d25d3a..a7bf0b8 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/AddressDescriptorEventListener.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/AddressDescriptorEventListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,12 +9,17 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.models.events;
-import java.util.Vector;
-import org.eclipse.persistence.descriptors.*;
-import org.eclipse.persistence.testing.framework.*;
+import java.util.List;
+
+import org.eclipse.persistence.descriptors.DescriptorEvent;
+import org.eclipse.persistence.descriptors.DescriptorEventListener;
+import org.eclipse.persistence.descriptors.DescriptorEventManager;
+import org.eclipse.persistence.testing.framework.TestErrorException;
public class AddressDescriptorEventListener implements DescriptorEventListener {
public boolean preInsertExecuted;
@@ -60,7 +65,8 @@ public void checkRowEvent(DescriptorEvent event) {
}
}
- public boolean isOverriddenEvent(DescriptorEvent event, Vector eventManagers) {
+ @Override
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
return false;
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/CustomerDescriptorEventListener.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/CustomerDescriptorEventListener.java
index 2c2512a..3224524 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/CustomerDescriptorEventListener.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/CustomerDescriptorEventListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,12 +9,17 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.models.events;
-import java.util.Vector;
-import org.eclipse.persistence.descriptors.*;
-import org.eclipse.persistence.queries.*;
+import java.util.List;
+
+import org.eclipse.persistence.descriptors.DescriptorEvent;
+import org.eclipse.persistence.descriptors.DescriptorEventListener;
+import org.eclipse.persistence.descriptors.DescriptorEventManager;
+import org.eclipse.persistence.queries.ObjectLevelModifyQuery;
public class CustomerDescriptorEventListener implements DescriptorEventListener {
public void aboutToInsert(DescriptorEvent event) {
@@ -26,7 +31,8 @@ public void aboutToDelete(DescriptorEvent event) {
public void aboutToUpdate(DescriptorEvent event) {
}
- public boolean isOverriddenEvent(DescriptorEvent event, Vector eventManagers) {
+ @Override
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
return false;
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/Phone.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/Phone.java
index 2bad9ed..13c3a04 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/Phone.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/events/Phone.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,11 +9,17 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.models.events;
-import java.util.Vector;
-import org.eclipse.persistence.descriptors.*;
+import java.util.List;
+
+import org.eclipse.persistence.descriptors.DescriptorEvent;
+import org.eclipse.persistence.descriptors.DescriptorEventListener;
+import org.eclipse.persistence.descriptors.DescriptorEventManager;
+import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;
public class Phone implements DescriptorEventListener {
@@ -84,7 +90,8 @@ public static Phone example2() {
return phone;
}
- public boolean isOverriddenEvent(DescriptorEvent event, Vector eventManagers) {
+ @Override
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
return false;
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/events/EventHookTestCase.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/events/EventHookTestCase.java
index 276bd7f..40fc253 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/events/EventHookTestCase.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/events/EventHookTestCase.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,6 +9,8 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.tests.events;
@@ -70,6 +72,6 @@ public void setup() {
setEmailAccount(EmailAccount.example1());
setPhoneNumber(Phone.example1());
setAddress(Address.example1());
- setAddressListener((AddressDescriptorEventListener)getSession().getDescriptor(Address.class).getEventManager().getEventListeners().firstElement());
+ setAddressListener((AddressDescriptorEventListener)getSession().getDescriptor(Address.class).getEventManager().getEventListeners().get(0));
}
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/nondeferredwrites/EmployeeDescriptorEventListener.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/nondeferredwrites/EmployeeDescriptorEventListener.java
index 2c5d0cb..40ee049 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/nondeferredwrites/EmployeeDescriptorEventListener.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/nondeferredwrites/EmployeeDescriptorEventListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,14 +9,17 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.tests.nondeferredwrites;
-import java.util.Vector;
+import java.util.List;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorEventListener;
-import org.eclipse.persistence.testing.framework.*;
+import org.eclipse.persistence.descriptors.DescriptorEventManager;
+import org.eclipse.persistence.testing.framework.TestErrorException;
public class EmployeeDescriptorEventListener implements DescriptorEventListener {
public boolean postInsertExecuted = false;
@@ -102,7 +105,8 @@ public void preWrite(DescriptorEvent event) {
* Implementers should define this method if they need or want to restrict
* the calling of inherited events.
*/
- public boolean isOverriddenEvent(DescriptorEvent event, Vector eventManagers) {
+ @Override
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
return false;
}
diff --git a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/workbenchintegration/EventListenerCollectionTest.java b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/workbenchintegration/EventListenerCollectionTest.java
index 9cca417..c3604f6 100644
--- a/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/workbenchintegration/EventListenerCollectionTest.java
+++ b/foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/workbenchintegration/EventListenerCollectionTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,17 +9,22 @@
*
* Contributors:
* John Vandale - initial API and implementation
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.testing.tests.workbenchintegration;
import java.io.File;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.persistence.descriptors.ClassDescriptor;
-import org.eclipse.persistence.testing.models.employee.relational.EmployeeProject;
+import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
+import org.eclipse.persistence.descriptors.DescriptorEventListener;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLProjectWriter;
-import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
+import org.eclipse.persistence.testing.models.employee.relational.EmployeeProject;
/**
* Bug 295383
@@ -53,11 +58,11 @@ public void verify() {
ClassDescriptor descriptor =
project.getDescriptors().get(Employee.class);
- java.util.Vector listeners = descriptor.getEventManager().getEventListeners();
+ List<DescriptorEventListener> listeners = descriptor.getEventManager().getEventListeners();
//test that the collection type is a NonSynchronizedVector
- if (!(listeners instanceof org.eclipse.persistence.internal.helper.NonSynchronizedVector)) {
- throwError("Descriptor from project XML with event listeners does not use NonSynchronizedVector for event listeners collection.");
+ if (!(listeners instanceof CopyOnWriteArrayList)) {
+ throwError("Descriptor from project XML with event listeners does not use CopyOnWriteArrayList for event listeners collection.");
}
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventAdapter.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventAdapter.java
index 8707cd1..2ad94c5 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventAdapter.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,10 +9,12 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.descriptors;
-import java.util.Vector;
+import java.util.List;
/**
* <p><b>Purpose</b>: Provides an empty implementation of DescriptorEventListener.
@@ -29,7 +31,8 @@ public void aboutToUpdate(DescriptorEvent event) {}
public void aboutToDelete(DescriptorEvent event) {}
- public boolean isOverriddenEvent(DescriptorEvent event, Vector<DescriptorEventManager> eventManagers) {
+ @Override
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
return false;
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventListener.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventListener.java
index f5ac180..b9b6664 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventListener.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,10 +9,13 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.descriptors;
-import java.util.*;
+import java.util.EventListener;
+import java.util.List;
/**
* <p><b>Purpose</b>: Used to support Java event listener event model on descriptors.
@@ -34,14 +37,14 @@ public interface DescriptorEventListener extends EventListener {
* This event can be used to amend an object's delete row.
*/
// CR#2660080 was missing aboutToDelete
- public void aboutToDelete(DescriptorEvent event);
+ void aboutToDelete(DescriptorEvent event);
/**
* This event is raised before a new object is inserted to the database.
* The object's row has already been built and is accessible from the event.
* This event can be used to amend an object's insert row.
*/
- public void aboutToInsert(DescriptorEvent event);
+ void aboutToInsert(DescriptorEvent event);
/**
* This event is raised before an object is updated in the database.
@@ -49,19 +52,19 @@ public interface DescriptorEventListener extends EventListener {
* The object's row has already been built and is accessible from the event.
* This event can be used to amend an object's update row.
*/
- public void aboutToUpdate(DescriptorEvent event);
+ void aboutToUpdate(DescriptorEvent event);
/**
* Implementers should define this method if they need or want to restrict
* the calling of inherited events.
*/
- public boolean isOverriddenEvent(DescriptorEvent event, Vector<DescriptorEventManager> eventManagers);
+ boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers);
/**
* This event is raised after an object is built from its row on a read operation.
* This event can be used to initialize non-persistent or non-mapped state in the object.
*/
- public void postBuild(DescriptorEvent event);
+ void postBuild(DescriptorEvent event);
/**
* This event is raised after an object is cloned into a unit of work.
@@ -69,17 +72,17 @@ public interface DescriptorEventListener extends EventListener {
* The event source/object is the unit of work clone,
* the event originalObject is the original object from the session cache.
*/
- public void postClone(DescriptorEvent event);
+ void postClone(DescriptorEvent event);
/**
* This event is raised after an object is deleted from the database.
*/
- public void postDelete(DescriptorEvent event);
+ void postDelete(DescriptorEvent event);
/**
* This event is raised after an object is inserted to the database.
*/
- public void postInsert(DescriptorEvent event);
+ void postInsert(DescriptorEvent event);
/**
* This event is raised after an object is merged from a unit of work into its parent.
@@ -87,46 +90,46 @@ public interface DescriptorEventListener extends EventListener {
* The event source/object is the parent session object that was merged into,
* the event originalObject is the unit of work clone that was merged from.
*/
- public void postMerge(DescriptorEvent event);
+ void postMerge(DescriptorEvent event);
/**
* This event is raised after an object is refreshed from its row on a refresh operation.
* This event can be used to initialize non-persistent or non-mapped state in the object.
*/
- public void postRefresh(DescriptorEvent event);
+ void postRefresh(DescriptorEvent event);
/**
* This event is raised after an object updated in the database.
* This event is only raised for objects that had changes and were updated.
*/
- public void postUpdate(DescriptorEvent event);
+ void postUpdate(DescriptorEvent event);
/**
* This event is raised after an object is inserted or updated in the database.
* This event is only raised for new objects or objects that had changes and were updated.
*/
- public void postWrite(DescriptorEvent event);
+ void postWrite(DescriptorEvent event);
/**
* This event is raised before an object is deleted from the database.
*/
- public void preDelete(DescriptorEvent event);
+ void preDelete(DescriptorEvent event);
/**
* This event is raised before an object is inserted to the database.
*/
- public void preInsert(DescriptorEvent event);
+ void preInsert(DescriptorEvent event);
/**
* This event is only raised by the EntityManager. It is raised when the
* create operation is initiated on an object.
*/
- public void prePersist(DescriptorEvent event);
+ void prePersist(DescriptorEvent event);
/**
* This event is raised when the remove operation is initiated on an object.
*/
- public void preRemove(DescriptorEvent event);
+ void preRemove(DescriptorEvent event);
/**
* This event is raised for all existing objects written or committed in a unit of work.
@@ -134,7 +137,7 @@ public interface DescriptorEventListener extends EventListener {
* so the object may still be modified by the event.
* If the object has no changes, it will not be updated in a unit of work.
*/
- public void preUpdate(DescriptorEvent event);
+ void preUpdate(DescriptorEvent event);
/**
* This event is raised before an object is updated regardless if the object
@@ -143,7 +146,7 @@ public interface DescriptorEventListener extends EventListener {
* event. For objects that have database changes, an aboutToUpdate will also
* be triggered.
*/
- public void preUpdateWithChanges(DescriptorEvent event);
+ void preUpdateWithChanges(DescriptorEvent event);
/**
* This event is raised for all new or existing objects written or committed in a unit of work.
@@ -151,5 +154,6 @@ public interface DescriptorEventListener extends EventListener {
* so the object may still be modified by the event.
* If the object is existing and has no changes, it will not be updated in a unit of work.
*/
- public void preWrite(DescriptorEvent event);
+ void preWrite(DescriptorEvent event);
+
}
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventManager.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventManager.java
index 1df87f7..a15eb45 100644
--- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventManager.java
+++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/DescriptorEventManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -9,6 +9,8 @@
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.descriptors;
@@ -19,13 +21,13 @@
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReferenceArray;
import org.eclipse.persistence.core.descriptors.CoreDescriptorEventManager;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
-import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.sessions.AbstractSession;
@@ -54,29 +56,29 @@
*/
public class DescriptorEventManager extends CoreDescriptorEventManager<DescriptorEvent> implements Cloneable, Serializable {
protected ClassDescriptor descriptor;
- protected Vector eventSelectors;
- protected transient Vector eventMethods;
- protected transient Vector eventListeners;
+ protected AtomicReferenceArray<String> eventSelectors;
+ protected transient AtomicReferenceArray<Method> eventMethods;
+ protected transient List<DescriptorEventListener> eventListeners;
// EJB 3.0 support for event listeners.
- protected transient Vector defaultEventListeners;
- protected transient Vector entityListenerEventListeners;
+ protected transient List<DescriptorEventListener> defaultEventListeners;
+ protected transient List<DescriptorEventListener> entityListenerEventListeners;
protected transient DescriptorEventListener entityEventListener;
/**
* Listeners that are fired after all other listeners are fired
*/
- protected transient List<DescriptorEventListener> internalListeners = new ArrayList<DescriptorEventListener>();
+ protected transient List<DescriptorEventListener> internalListeners = new ArrayList<>();
// EJB 3.0 support - cache our parent event managers.
- protected transient Vector entityEventManagers;
- protected transient Vector entityListenerEventManagers;
+ protected transient List<DescriptorEventManager> entityEventManagers;
+ protected transient List<DescriptorEventManager> entityListenerEventManagers;
// EJB 3.0 support for event listener configuration flags.
protected boolean excludeDefaultListeners;
protected boolean excludeSuperclassListeners;
//JPA project caching support. Holds DescriptorEventListener representations for serialization/storage.
- protected java.util.List<SerializableDescriptorEventHolder> descriptorEventHolders;
+ protected List<SerializableDescriptorEventHolder> descriptorEventHolders;
/** PERF: Cache if any events listener exist. */
protected boolean hasAnyEventListeners;
@@ -103,22 +105,18 @@ public class DescriptorEventManager extends CoreDescriptorEventManager<Descripto
public static final int PreRemoveEvent = 16;
public static final int PreUpdateWithChangesEvent = 17;
- protected static final int NumberOfEvents = 18;
+ protected static final int NumberOfEvents = 18;
+
/**
* INTERNAL:
* Returns a new DescriptorEventManager for the specified ClassDescriptor.
*/
public DescriptorEventManager() {
- this.eventSelectors = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(NumberOfEvents);
- this.eventMethods = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(NumberOfEvents);
+ this.eventSelectors = newAtomicReferenceArray(NumberOfEvents);
+ this.eventMethods = newAtomicReferenceArray(NumberOfEvents);
this.hasAnyEventListeners = false;
this.excludeDefaultListeners = false;
this.excludeSuperclassListeners = false;
-
- for (int index = 0; index < NumberOfEvents; index++) {
- this.eventSelectors.addElement(null);
- this.eventMethods.addElement(null);
- }
}
/**
@@ -126,7 +124,7 @@ public DescriptorEventManager() {
* EJB 3.0 support for default listeners.
*/
public void addDefaultEventListener(DescriptorEventListener listener) {
- getDefaultEventListeners().addElement(listener);
+ getDefaultEventListeners().add(listener);
}
/**
@@ -135,7 +133,7 @@ public void addDefaultEventListener(DescriptorEventListener listener) {
* listener class.
*/
public void addEntityListenerEventListener(DescriptorEventListener listener) {
- getEntityListenerEventListeners().addElement(listener);
+ getEntityListenerEventListeners().add(listener);
}
/**
@@ -144,7 +142,7 @@ public void addEntityListenerEventListener(DescriptorEventListener listener) {
* when an event occurs on any instance of the descriptor's class.
*/
public void addListener(DescriptorEventListener listener) {
- getEventListeners().addElement(listener);
+ getEventListeners().add(listener);
setHasAnyEventListeners(true);
}
@@ -154,7 +152,7 @@ public void addListener(DescriptorEventListener listener) {
*/
public void addInternalListener(DescriptorEventListener listener) {
if (internalListeners==null) {
- internalListeners = new ArrayList<DescriptorEventListener>();
+ internalListeners = new ArrayList<>();
}
internalListeners.add(listener);
setHasAnyEventListeners(true); // ensure that events are generated
@@ -176,8 +174,8 @@ public void addEntityListenerHolder(SerializableDescriptorEventHolder holder) {
public Object clone() {
try {
DescriptorEventManager clone = (DescriptorEventManager)super.clone();
- clone.setEventSelectors((Vector)getEventSelectors().clone());
- clone.setEventMethods((Vector)getEventMethods().clone());
+ clone.setEventSelectors(newAtomicReferenceArray(getEventSelectors()));
+ clone.setEventMethods(newAtomicReferenceArray(getEventMethods()));
clone.setEventListeners(getEventListeners());
return clone;
} catch (Exception exception) {
@@ -238,7 +236,7 @@ public void executeEvent(DescriptorEvent event) throws DescriptorException {
return;
}
- Method eventMethod = (Method)getEventMethods().elementAt(event.getEventCode());
+ Method eventMethod = (Method)getEventMethods().get(event.getEventCode());
if (eventMethod == null) {
return;
}
@@ -281,7 +279,7 @@ public void executeEvent(DescriptorEvent event) throws DescriptorException {
protected Method findMethod(int selector) throws DescriptorException {
Class[] declarationParameters = new Class[1];
declarationParameters[0] = ClassConstants.DescriptorEvent_Class;
- String methodName = (String)getEventSelectors().elementAt(selector);
+ String methodName = getEventSelectors().get(selector);
try {
return Helper.getDeclaredMethod(getDescriptor().getJavaClass(), methodName, declarationParameters);
@@ -297,32 +295,31 @@ protected Method findMethod(int selector) throws DescriptorException {
* bug 251180 - Missing method org.eclipse.persistence.descriptors.DescriptorEventManager#setAboutToDeleteSelector
*/
public String getAboutToDeleteSelector() {
- return (String)getEventSelectors().elementAt(AboutToDeleteEvent);
+ return getEventSelectors().get(AboutToDeleteEvent);
}
/**
* INTERNAL:
*/
public String getAboutToInsertSelector() {
- return (String)getEventSelectors().elementAt(AboutToInsertEvent);
+ return getEventSelectors().get(AboutToInsertEvent);
}
/**
* INTERNAL:
*/
public String getAboutToUpdateSelector() {
- return (String)getEventSelectors().elementAt(AboutToUpdateEvent);
+ return getEventSelectors().get(AboutToUpdateEvent);
}
/**
* INTERNAL:
* EJB 3.0 support. Returns the default listeners.
*/
- public Vector getDefaultEventListeners() {
+ public List<DescriptorEventListener> getDefaultEventListeners() {
if (defaultEventListeners == null) {
- defaultEventListeners = new NonSynchronizedVector();
+ defaultEventListeners = new CopyOnWriteArrayList<>();
}
-
return defaultEventListeners;
}
@@ -338,9 +335,9 @@ protected ClassDescriptor getDescriptor() {
* used by JPA project caching to store DescriptorEventListener representations that can build the underlying
* DescriptorEventListener and add it to the EventManager.
*/
- public java.util.List<SerializableDescriptorEventHolder> getDescriptorEventHolders() {
+ public List<SerializableDescriptorEventHolder> getDescriptorEventHolders() {
if (descriptorEventHolders == null) {
- descriptorEventHolders = new java.util.ArrayList();
+ descriptorEventHolders = new CopyOnWriteArrayList<>();
}
return descriptorEventHolders;
}
@@ -350,7 +347,7 @@ public java.util.List<SerializableDescriptorEventHolder> getDescriptorEventHolde
* used by JPA project caching to store DescriptorEventListener representations that can build the underlying
* DescriptorEventListener and add it to the EventManager.
*/
- public void setDescriptorEventHolders(java.util.List<SerializableDescriptorEventHolder> descriptorEventHolders) {
+ public void setDescriptorEventHolders(List<SerializableDescriptorEventHolder> descriptorEventHolders) {
this.descriptorEventHolders = descriptorEventHolders;
}
@@ -366,11 +363,10 @@ public DescriptorEventListener getEntityEventListener() {
* INTERNAL:
* EJB 3.0 support. Returns the entity listener event listeners.
*/
- public Vector getEntityListenerEventListeners() {
+ public List<DescriptorEventListener> getEntityListenerEventListeners() {
if (entityListenerEventListeners == null) {
- entityListenerEventListeners = new Vector();
+ entityListenerEventListeners = new CopyOnWriteArrayList<>();
}
-
return entityListenerEventListeners;
}
@@ -380,31 +376,25 @@ public Vector getEntityListenerEventListeners() {
*
* @see #addListener(DescriptorEventListener)
*/
- public Vector getEventListeners() {
+ public List<DescriptorEventListener> getEventListeners() {
// Lazy initialize to avoid unnecessary enumerations.
if (eventListeners == null) {
- eventListeners = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(1);
+ eventListeners = new CopyOnWriteArrayList<>();
}
return eventListeners;
}
- protected Vector getEventMethods() {
+ protected AtomicReferenceArray<Method> getEventMethods() {
//Lazy Initialized to prevent Null Pointer exception after serialization
if (this.eventMethods == null) {
- this.eventMethods = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(NumberOfEvents);
- for (int index = 0; index < NumberOfEvents; ++index) {
- this.eventMethods.addElement(null);
- }
+ this.eventMethods = newAtomicReferenceArray(NumberOfEvents);
}
return eventMethods;
}
- protected Vector getEventSelectors() {
+ protected AtomicReferenceArray<String> getEventSelectors() {
if (this.eventSelectors == null) {
- this.eventSelectors = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(NumberOfEvents);
- for (int index = 0; index < NumberOfEvents; ++index) {
- this.eventSelectors.addElement(null);
- }
+ this.eventSelectors = newAtomicReferenceArray(NumberOfEvents);
}
return eventSelectors;
}
@@ -414,7 +404,7 @@ protected Vector getEventSelectors() {
* The name of the method called after an object is built
*/
public String getPostBuildSelector() {
- return (String)getEventSelectors().elementAt(PostBuildEvent);
+ return getEventSelectors().get(PostBuildEvent);
}
/**
@@ -422,7 +412,7 @@ public String getPostBuildSelector() {
* The name of the method called after an object is cloned
*/
public String getPostCloneSelector() {
- return (String)getEventSelectors().elementAt(PostCloneEvent);
+ return getEventSelectors().get(PostCloneEvent);
}
/**
@@ -430,7 +420,7 @@ public String getPostCloneSelector() {
* The name of the method called after an object is deleted
*/
public String getPostDeleteSelector() {
- return (String)getEventSelectors().elementAt(PostDeleteEvent);
+ return getEventSelectors().get(PostDeleteEvent);
}
/**
@@ -438,7 +428,7 @@ public String getPostDeleteSelector() {
* The name of the method called after an object is inserted
*/
public String getPostInsertSelector() {
- return (String)getEventSelectors().elementAt(PostInsertEvent);
+ return getEventSelectors().get(PostInsertEvent);
}
/**
@@ -446,7 +436,7 @@ public String getPostInsertSelector() {
* The name of the method called after an object is merged
*/
public String getPostMergeSelector() {
- return (String)getEventSelectors().elementAt(PostMergeEvent);
+ return getEventSelectors().get(PostMergeEvent);
}
/**
@@ -454,7 +444,7 @@ public String getPostMergeSelector() {
* The name of the method called after an object is refreshed
*/
public String getPostRefreshSelector() {
- return (String)getEventSelectors().elementAt(PostRefreshEvent);
+ return getEventSelectors().get(PostRefreshEvent);
}
/**
@@ -462,7 +452,7 @@ public String getPostRefreshSelector() {
* The name of the method called after an object is updated
*/
public String getPostUpdateSelector() {
- return (String)getEventSelectors().elementAt(PostUpdateEvent);
+ return getEventSelectors().get(PostUpdateEvent);
}
/**
@@ -470,7 +460,7 @@ public String getPostUpdateSelector() {
* The name of the method called after an object is written
*/
public String getPostWriteSelector() {
- return (String)getEventSelectors().elementAt(PostWriteEvent);
+ return getEventSelectors().get(PostWriteEvent);
}
/**
@@ -478,7 +468,7 @@ public String getPostWriteSelector() {
* The name of the method called before the create operation is applied to an object
*/
public String getPrePersistSelector() {
- return (String)getEventSelectors().elementAt(PrePersistEvent);
+ return getEventSelectors().get(PrePersistEvent);
}
/**
@@ -486,7 +476,7 @@ public String getPrePersistSelector() {
* The name of the method called before an object is deleted
*/
public String getPreDeleteSelector() {
- return (String)getEventSelectors().elementAt(PreDeleteEvent);
+ return getEventSelectors().get(PreDeleteEvent);
}
/**
@@ -494,7 +484,7 @@ public String getPreDeleteSelector() {
* The name of the method called before an object is inserted
*/
public String getPreInsertSelector() {
- return (String)getEventSelectors().elementAt(PreInsertEvent);
+ return getEventSelectors().get(PreInsertEvent);
}
/**
@@ -502,7 +492,7 @@ public String getPreInsertSelector() {
* The name of the method called before the remove operation is applied to an object
*/
public String getPreRemoveSelector() {
- return (String)getEventSelectors().elementAt(PreRemoveEvent);
+ return getEventSelectors().get(PreRemoveEvent);
}
/**
@@ -510,7 +500,7 @@ public String getPreRemoveSelector() {
* The name of the method called before an object is updated
*/
public String getPreUpdateSelector() {
- return (String)getEventSelectors().elementAt(PreUpdateEvent);
+ return getEventSelectors().get(PreUpdateEvent);
}
/**
@@ -518,7 +508,7 @@ public String getPreUpdateSelector() {
* The name of the method called before an object is written
*/
public String getPreWriteSelector() {
- return (String)getEventSelectors().elementAt(PreWriteEvent);
+ return getEventSelectors().get(PreWriteEvent);
}
/**
@@ -563,7 +553,7 @@ public boolean hasEntityEventListener() {
* listener event listeners.
*/
public boolean hasInternalEventListeners() {
- return internalListeners != null && internalListeners.size() > 0;
+ return internalListeners != null && !internalListeners.isEmpty();
}
/**
@@ -572,7 +562,7 @@ public boolean hasInternalEventListeners() {
* listener event listeners.
*/
public boolean hasEntityListenerEventListeners() {
- return entityListenerEventListeners != null && entityListenerEventListeners.size() > 0;
+ return entityListenerEventListeners != null && !entityListenerEventListeners.isEmpty();
}
/**
@@ -592,10 +582,11 @@ public void initialize(AbstractSession session) {
setHasAnyEventListeners(true);
}
+ final AtomicReferenceArray<String> selectors = getEventSelectors();
for (int index = 0; index < NumberOfEvents; index++) {
- if (getEventSelectors().elementAt(index) != null) {
+ if (selectors.get(index) != null) {
setHasAnyEventListeners(true);
- getEventMethods().setElementAt(findMethod(index), index);
+ getEventMethods().set(index, findMethod(index));
}
}
@@ -608,9 +599,9 @@ public void initialize(AbstractSession session) {
}
for (int index = 0; index < NumberOfEvents; index++) {
- if ((getEventSelectors().get(index) == null) && (parentEventManager.getEventSelectors().get(index) != null)) {
+ if ((selectors.get(index) == null) && (parentEventManager.getEventSelectors().get(index) != null)) {
setHasAnyEventListeners(true);
- getEventSelectors().set(index, parentEventManager.getEventSelectors().get(index));
+ selectors.set(index, parentEventManager.getEventSelectors().get(index));
getEventMethods().set(index, parentEventManager.getEventMethods().get(index));
}
}
@@ -624,8 +615,8 @@ public void initialize(AbstractSession session) {
* once.
*/
protected void initializeEJB30EventManagers() {
- entityEventManagers = new NonSynchronizedVector();
- entityListenerEventManagers = new NonSynchronizedVector();
+ entityEventManagers = new CopyOnWriteArrayList<>();
+ entityListenerEventManagers = new CopyOnWriteArrayList<>();
if (hasEntityEventListener()) {
entityEventManagers.add(this);
@@ -672,7 +663,7 @@ protected void notifyEJB30Listeners(DescriptorEvent event) {
// Step 2 - Notify the Entity Listener's first, top -> down.
for (int index = entityListenerEventManagers.size() - 1; index >= 0; index--) {
- Vector entityListenerEventListeners = ((DescriptorEventManager) entityListenerEventManagers.get(index)).getEntityListenerEventListeners();
+ List entityListenerEventListeners = ((DescriptorEventManager) entityListenerEventManagers.get(index)).getEntityListenerEventListeners();
for (int i = 0; i < entityListenerEventListeners.size(); i++) {
DescriptorEventListener listener = (DescriptorEventListener) entityListenerEventListeners.get(i);
@@ -683,7 +674,7 @@ protected void notifyEJB30Listeners(DescriptorEvent event) {
// Step 3 - Notify the Entity event listeners. top -> down, unless
// they are overridden in a subclass.
for (int index = entityEventManagers.size() - 1; index >= 0; index--) {
- DescriptorEventListener entityEventListener = ((DescriptorEventManager) entityEventManagers.get(index)).getEntityEventListener();
+ DescriptorEventListener entityEventListener = entityEventManagers.get(index).getEntityEventListener();
if (! entityEventListener.isOverriddenEvent(event, entityEventManagers)) {
notifyListener(entityEventListener, event);
@@ -786,12 +777,7 @@ public void notifyListeners(DescriptorEvent event) {
* Used to initialize a remote DescriptorEventManager.
*/
public void remoteInitialization(AbstractSession session) {
- this.eventMethods = new Vector(NumberOfEvents);
-
- for (int index = 0; index < NumberOfEvents; index++) {
- this.eventMethods.addElement(null);
- }
-
+ this.eventMethods = newAtomicReferenceArray(NumberOfEvents);
initialize(session);
}
@@ -800,7 +786,7 @@ public void remoteInitialization(AbstractSession session) {
* Remove a event listener.
*/
public void removeListener(DescriptorEventListener listener) {
- getEventListeners().removeElement(listener);
+ getEventListeners().remove(listener);
}
/**
@@ -813,7 +799,7 @@ public void removeListener(DescriptorEventListener listener) {
*/
//bug 251180: Missing method org.eclipse.persistence.descriptors.DescriptorEventManager#setAboutToDeleteSelector
public void setAboutToDeleteSelector(String aboutToDeleteSelector) {
- getEventSelectors().setElementAt(aboutToDeleteSelector, AboutToDeleteEvent);
+ getEventSelectors().set(AboutToDeleteEvent, aboutToDeleteSelector);
}
/**
@@ -825,7 +811,7 @@ public void setAboutToDeleteSelector(String aboutToDeleteSelector) {
* insert, such as adding a user inserted by.
*/
public void setAboutToInsertSelector(String aboutToInsertSelector) {
- getEventSelectors().setElementAt(aboutToInsertSelector, AboutToInsertEvent);
+ getEventSelectors().set(AboutToInsertEvent, aboutToInsertSelector);
}
/**
@@ -838,7 +824,7 @@ public void setAboutToInsertSelector(String aboutToInsertSelector) {
* to modify the row before insert, such as adding a user inserted by.
*/
public void setAboutToUpdateSelector(String aboutToUpdateSelector) {
- getEventSelectors().setElementAt(aboutToUpdateSelector, AboutToUpdateEvent);
+ getEventSelectors().set(AboutToUpdateEvent, aboutToUpdateSelector);
}
/**
@@ -857,15 +843,19 @@ public void setEntityEventListener(DescriptorEventListener listener) {
this.entityEventListener = listener;
}
- protected void setEventListeners(Vector eventListeners) {
- this.eventListeners = eventListeners;
+ protected void setEventListeners(List<DescriptorEventListener> eventListeners) {
+ if (eventListeners instanceof CopyOnWriteArrayList) {
+ this.eventListeners = eventListeners;
+ } else {
+ this.eventListeners = new CopyOnWriteArrayList(eventListeners);
+ }
}
- protected void setEventMethods(Vector eventMethods) {
+ protected void setEventMethods(AtomicReferenceArray<Method> eventMethods) {
this.eventMethods = eventMethods;
}
- protected void setEventSelectors(Vector eventSelectors) {
+ protected void setEventSelectors(AtomicReferenceArray<String> eventSelectors) {
this.eventSelectors = eventSelectors;
}
@@ -909,7 +899,7 @@ protected void setHasAnyEventListeners(boolean hasAnyEventListeners) {
* mappings. This event is called whenever an object is built.
*/
public void setPostBuildSelector(String postBuildSelector) {
- getEventSelectors().setElementAt(postBuildSelector, PostBuildEvent);
+ getEventSelectors().set(PostBuildEvent, postBuildSelector);
}
/**
@@ -920,7 +910,7 @@ public void setPostBuildSelector(String postBuildSelector) {
* to correctly initialize an object's non-persistent attributes.
*/
public void setPostCloneSelector(String postCloneSelector) {
- getEventSelectors().setElementAt(postCloneSelector, PostCloneEvent);
+ getEventSelectors().set(PostCloneEvent, postCloneSelector);
}
/**
@@ -930,7 +920,7 @@ public void setPostCloneSelector(String postCloneSelector) {
* on the object.
*/
public void setPostDeleteSelector(String postDeleteSelector) {
- getEventSelectors().setElementAt(postDeleteSelector, PostDeleteEvent);
+ getEventSelectors().set(PostDeleteEvent, postDeleteSelector);
}
/**
@@ -941,7 +931,7 @@ public void setPostDeleteSelector(String postDeleteSelector) {
* the object has been inserted.
*/
public void setPostInsertSelector(String postInsertSelector) {
- getEventSelectors().setElementAt(postInsertSelector, PostInsertEvent);
+ getEventSelectors().set(PostInsertEvent, postInsertSelector);
}
/**
@@ -953,7 +943,7 @@ public void setPostInsertSelector(String postInsertSelector) {
* initialize an object's non-persistent attributes.
*/
public void setPostMergeSelector(String postMergeSelector) {
- getEventSelectors().setElementAt(postMergeSelector, PostMergeEvent);
+ getEventSelectors().set(PostMergeEvent, postMergeSelector);
}
/**
@@ -965,7 +955,7 @@ public void setPostMergeSelector(String postMergeSelector) {
* mappings. This event is only called on refreshes of existing objects.
*/
public void setPostRefreshSelector(String postRefreshSelector) {
- getEventSelectors().setElementAt(postRefreshSelector, PostRefreshEvent);
+ getEventSelectors().set(PostRefreshEvent, postRefreshSelector);
}
/**
@@ -974,7 +964,7 @@ public void setPostRefreshSelector(String postRefreshSelector) {
* updated into the database.
*/
public void setPostUpdateSelector(String postUpdateSelector) {
- getEventSelectors().setElementAt(postUpdateSelector, PostUpdateEvent);
+ getEventSelectors().set(PostUpdateEvent, postUpdateSelector);
}
/**
@@ -988,7 +978,7 @@ public void setPostUpdateSelector(String postUpdateSelector) {
* event can be used to notify any dependent on the object.
*/
public void setPostWriteSelector(String postWriteSelector) {
- getEventSelectors().setElementAt(postWriteSelector, PostWriteEvent);
+ getEventSelectors().set(PostWriteEvent, postWriteSelector);
}
/**
@@ -998,7 +988,7 @@ public void setPostWriteSelector(String postWriteSelector) {
* on the object.
*/
public void setPreDeleteSelector(String preDeleteSelector) {
- getEventSelectors().setElementAt(preDeleteSelector, PreDeleteEvent);
+ getEventSelectors().set(PreDeleteEvent, preDeleteSelector);
}
/**
@@ -1009,7 +999,7 @@ public void setPreDeleteSelector(String preDeleteSelector) {
* mechanism.
*/
public void setPreInsertSelector(String preInsertSelector) {
- getEventSelectors().setElementAt(preInsertSelector, PreInsertEvent);
+ getEventSelectors().set(PreInsertEvent, preInsertSelector);
}
/**
@@ -1018,7 +1008,7 @@ public void setPreInsertSelector(String preInsertSelector) {
* the create operation applied to it.
*/
public void setPrePersistSelector(String prePersistSelector) {
- getEventSelectors().setElementAt(prePersistSelector, PrePersistEvent);
+ getEventSelectors().set(PrePersistEvent, prePersistSelector);
}
/**
@@ -1027,7 +1017,7 @@ public void setPrePersistSelector(String prePersistSelector) {
* the remove operation applied to it.
*/
public void setPreRemoveSelector(String preRemoveSelector) {
- getEventSelectors().setElementAt(preRemoveSelector, PreRemoveEvent);
+ getEventSelectors().set(PreRemoveEvent, preRemoveSelector);
}
/**
@@ -1040,7 +1030,7 @@ public void setPreRemoveSelector(String preRemoveSelector) {
* any dependent on the object.
*/
public void setPreUpdateSelector(String preUpdateSelector) {
- getEventSelectors().setElementAt(preUpdateSelector, PreUpdateEvent);
+ getEventSelectors().set(PreUpdateEvent, preUpdateSelector);
}
/**
@@ -1054,6 +1044,32 @@ public void setPreUpdateSelector(String preUpdateSelector) {
* event can be used to notify any dependent on the object.
*/
public void setPreWriteSelector(String preWriteSelector) {
- getEventSelectors().setElementAt(preWriteSelector, PreWriteEvent);
+ getEventSelectors().set(PreWriteEvent, preWriteSelector);
}
+
+ /**
+ * Create an instance of {@link AtomicIntegerArray} initialized with {@code NullEvent} values.
+ *
+ * @param length length of the array.
+ * @return initialized instance of {@link AtomicIntegerArray}
+ */
+ private static <T> AtomicReferenceArray<T> newAtomicReferenceArray(final int length) {
+ final AtomicReferenceArray array = new AtomicReferenceArray<>(length);
+ for (int index = 0; index < length; array.set(index++, null));
+ return (AtomicReferenceArray<T>)array;
+ }
+
+ /**
+ * Create an instance of {@link AtomicIntegerArray} initialized with content of provided array.
+ *
+ * @param src source array.
+ * @return initialized instance of {@link AtomicIntegerArray}
+ */
+ private static <T> AtomicReferenceArray<T> newAtomicReferenceArray(final AtomicReferenceArray<T> src) {
+ final int length = src.length();
+ final AtomicReferenceArray array = new AtomicReferenceArray<>(length);
+ for (int index = 0; index < length; array.set(index, src.get(index++)));
+ return (AtomicReferenceArray<T>)array;
+ }
+
}
diff --git a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/EntityListener.java b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/EntityListener.java
index f8d2845..465b0dd 100644
--- a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/EntityListener.java
+++ b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/EntityListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -14,6 +14,8 @@
* - 211324: Add additional event(s) support to the EclipseLink-ORM.XML Schema
* 07/15/2010-2.2 Guy Pelletier
* -311395 : Multiple lifecycle callback methods for the same lifecycle event
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.internal.jpa.metadata.listeners;
@@ -25,10 +27,9 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
@@ -62,8 +63,8 @@ public class EntityListener<T> extends DescriptorEventAdapter {
private T m_listener;
private Class<T> m_listenerClass;
private Class m_entityClass;
- private Hashtable<String, List<Method>> m_methods;
- private Hashtable<String, Hashtable<Integer, Boolean>> m_overriddenEvents;
+ private Map<String, List<Method>> m_methods;
+ private final Map<String, Map<Integer, Boolean>> m_overriddenEvents;
private static final Map<Integer, String> m_eventStrings;
private AbstractSession owningSession;
@@ -86,11 +87,11 @@ public class EntityListener<T> extends DescriptorEventAdapter {
*/
protected EntityListener(Class entityClass) {
m_entityClass = entityClass;
- m_methods = new Hashtable<>();
+ m_methods = new ConcurrentHashMap<>();
// Remember which events are overridden in subclasses. Overridden events
// must be built for each subclass chain.
- m_overriddenEvents = new Hashtable<>();
+ m_overriddenEvents = new ConcurrentHashMap<>();
}
public EntityListener(Class<T> listenerClass, Class entityClass){
@@ -178,14 +179,14 @@ public Class getEntityClass() {
/**
* INTERNAL:
*/
- public Hashtable<String, List<Method>> getAllEventMethods() {
+ public Map<String, List<Method>> getAllEventMethods() {
return m_methods;
}
/**
* INTERNAL:
*/
- public void setAllEventMethods(Hashtable<String, List<Method>> methods) {
+ public void setAllEventMethods(Map<String, List<Method>> methods) {
m_methods = methods;
}
@@ -201,12 +202,7 @@ public void setOwningSession(AbstractSession owningSession) {
*/
protected List<Method> getEventMethods(int eventCode) {
String eventString = m_eventStrings.get(eventCode);
-
- if (eventString != null) {
- return getEventMethods(eventString);
- } else {
- return null;
- }
+ return eventString != null ? getEventMethods(eventString) : null;
}
/**
@@ -356,14 +352,14 @@ void invokeMethod(String event, DescriptorEvent descriptorEvent) {
* overridden in a subclass.
*/
@Override
- public boolean isOverriddenEvent(DescriptorEvent event, Vector<DescriptorEventManager> eventManagers) {
+ public boolean isOverriddenEvent(DescriptorEvent event, List<DescriptorEventManager> eventManagers) {
int eventCode = event.getEventCode();
String forSubclass = event.getDescriptor().getJavaClassName();
- Hashtable<Integer, Boolean> subClassMap = m_overriddenEvents.get(forSubclass);
+ Map<Integer, Boolean> subClassMap = m_overriddenEvents.get(forSubclass);
// If we haven't built an overridden events map for this subclass, do so now.
if (subClassMap == null) {
- subClassMap = new Hashtable<>();
+ subClassMap = new ConcurrentHashMap<>();
}
// Now check the individual events for this subclass.
diff --git a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/JPAEntityListenerHolder.java b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/JPAEntityListenerHolder.java
index 00c88ee..a488d90 100644
--- a/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/JPAEntityListenerHolder.java
+++ b/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/listeners/JPAEntityListenerHolder.java
@@ -11,6 +11,8 @@
* Oracle - initial API and implementation
* 08/01/2012-2.5 Chris Delahunt
* - 371950: Metadata caching
+ * 12/14/2017-3.0 Tomas Kraus
+ * - 291546: Performance degradation due to usage of Vector in DescriptorEventManager
******************************************************************************/
package org.eclipse.persistence.internal.jpa.metadata.listeners;
@@ -18,8 +20,9 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorEventListener;
@@ -37,7 +40,7 @@ public class JPAEntityListenerHolder implements SerializableDescriptorEventHolde
public transient DescriptorEventListener listener;
- public java.util.Hashtable<String,java.util.List<MethodSerialImpl>> serializableMethods;
+ public Map<String,java.util.List<MethodSerialImpl>> serializableMethods;
public void setIsDefaultListener(Boolean isDefaultListener) {
this.isDefaultListener = isDefaultListener;
@@ -108,8 +111,8 @@ protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
- public void convertToSerializableMethods(java.util.Hashtable<String,java.util.List<Method>> methods) {
- this.serializableMethods = new java.util.Hashtable();
+ public void convertToSerializableMethods(Map<String,java.util.List<Method>> methods) {
+ this.serializableMethods = new ConcurrentHashMap<>();
for (String event: methods.keySet()){
java.util.List<Method> methodList = methods.get(event);
java.util.List<MethodSerialImpl> newMethodList = new java.util.ArrayList();
@@ -168,8 +171,8 @@ public void addEventMethod(String event, Method method) {
* @param loader
* @return
*/
- public java.util.Hashtable<String,java.util.List<Method>> convertToMethods(ClassLoader loader) {
- java.util.Hashtable<String,java.util.List<Method>> table = new java.util.Hashtable();
+ public Map<String,java.util.List<Method>> convertToMethods(ClassLoader loader) {
+ Map<String,java.util.List<Method>> table = new ConcurrentHashMap<>();
for (String event: serializableMethods.keySet()){
java.util.List<MethodSerialImpl> methodList = serializableMethods.get(event);
java.util.List<Method> newMethodList = new java.util.ArrayList();
@@ -186,9 +189,9 @@ public java.util.Hashtable<String,java.util.List<Method>> convertToMethods(Class
return table;
}
- public java.util.Hashtable<String,java.util.List<MethodSerialImpl>> getMethods() {
+ public Map<String,java.util.List<MethodSerialImpl>> getMethods() {
if (serializableMethods == null) {
- serializableMethods = new Hashtable<String, List<MethodSerialImpl>>();
+ serializableMethods = new ConcurrentHashMap<String, List<MethodSerialImpl>>();
}
return serializableMethods;
}