blob: 8ce8820a900312b40565e788404da3756314a295 [file] [log] [blame]
/*
* Copyright (c) 1998, 2019 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 v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// ailitchev - bug 235433: Can't customize ConnectionPolicy through JPA + some comments.
package org.eclipse.persistence.sessions.server;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.config.ExclusiveConnectionMode;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.sessions.Login;
/**
* <p>
* <b>Purpose</b>: Used to specify how a client session's should be allocated.
* <p>
* <b>Description</b>: The ConnectionPolicy is used to indicate how a client
* session will interact with the internal or external JDBC connection pool/data
* source. The default ConnectionPolicy is held on the ServerSession but this
* can be overridden for any specific client session when it is acquired.
*
* @see ServerSession#getDefaultConnectionPolicy()
* @see ServerSession#acquireClientSession(ConnectionPolicy)
* @see ServerSession#acquireClientSession(ConnectionPolicy, Map)
* @see ClientSession#getConnectionPolicy()
*/
public class ConnectionPolicy implements Cloneable, Serializable {
/**
* The login information used to create a JDBC connection or acquire one
* from an external pool/data-source. Typically this is constant within a
* single persistence unit but in some advanced usages users can customize
* connections for each client session.
*/
protected Login login;
/**
* Name of the pool to be used.
* If neither pool name nor login provided then default pool will be used.
* If no pool name is provided but there's a login then the login is used to
* create connection which the ClientSession will use.
*/
protected String poolName;
/**
* Determines if the write/exclusive connection is acquired only when first
* requested (lazy, this is the default) or immediately when the client
* session is acquired.
* After write/exclusive connection is acquired
* if isLazy is true and exclusiveMode is Transactional
* then it's held until transaction is committed or rolled back,
* otherwise until the client session is released.
*/
protected boolean isLazy;
/**
* Default value Transactional causes creation of ClientSession,
* the other two values - ExclusiveIsolatedClientSession.
* ExclusiveMode values correspond to ExclusiveConnectionMode values,
* the latter class has extensive comments explaining the differences between
* the values.
* @see ExclusiveConnectionMode
*/
public enum ExclusiveMode {
Transactional,
Isolated,
Always
}
/**
* This attribute is used by the ServerSession to determine if a client
* session with an exclusive connection should be built and how the exclusive
* connection should be used.
*/
protected ExclusiveMode exclusiveMode;
/**
* This attribute will provide a mechanism by which customers will be able
* to pass connection information to events to enable further customization.
*/
protected Map properties;
/**
* PUBLIC:
* A connection policy is used to define how the client session connection should be acquired.
*/
public ConnectionPolicy() {
this.isLazy = true;
this.exclusiveMode = ExclusiveMode.Transactional;
}
/**
* PUBLIC:
* A connection policy is used to define how the client session connection should be acquired.
*/
public ConnectionPolicy(String poolName) {
this.isLazy = true;
this.poolName = poolName;
this.exclusiveMode = ExclusiveMode.Transactional;
}
/**
* PUBLIC:
* A connection policy is used to define how the client session connection should be acquired.
*/
public ConnectionPolicy(Login login) {
this.isLazy = false;
this.login = login;
this.exclusiveMode = ExclusiveMode.Transactional;
}
/**
* INTERNAL:
* Clone the query
*/
@Override
public Object clone() {
try {
ConnectionPolicy clone = (ConnectionPolicy)super.clone();
if (clone.hasLogin()) {
clone.setLogin(clone.getLogin().clone());
}
return clone;
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* PUBLIC:
* A lazy connection only acquires a physical connection
* when a transaction is started and releases the connection when the transaction completes.
*/
public void dontUseLazyConnection() {
setIsLazy(false);
}
/**
* PUBLIC:
* Return the login to use for this connection.
* Client sessions support using a separate user login for database modification.
*/
public Login getLogin() {
return login;
}
/**
* PUBLIC:
* Return the pool name or null if not part of a pool.
*/
public String getPoolName() {
return poolName;
}
/**
* ADVANCED:
* This method will return the collection of custom properties set on the Connection
* policy. Note that this will cause the lazy initialization of the HashMap.
*/
public Map getProperties() {
if (this.properties == null) {
this.properties = new HashMap();
}
return this.properties;
}
/**
* PUBLIC:
* Returns the property associated with the corresponding key. These properties will be available to
* connection events.
*/
public Object getProperty(Object object) {
if (this.hasProperties()) {
return this.getProperties().get(object);
}
return null;
}
/**
* PUBLIC:
* Return if a login is used, only one of login and pool can be used.
*/
public boolean hasLogin() {
return login != null;
}
/**
* PUBLIC:
* Returns true if properties are available on the Connection Policy
*/
public boolean hasProperties() {
return (this.properties != null) && (!this.properties.isEmpty());
}
/**
* PUBLIC:
* Indicates whether exclusiveMode is Isolated.
*/
public boolean isExclusiveIsolated() {
return this.exclusiveMode == ExclusiveMode.Isolated;
}
/**
* PUBLIC:
* Indicates whether exclusiveMode is Always.
*/
public boolean isExclusiveAlways() {
return this.exclusiveMode == ExclusiveMode.Always;
}
/**
* PUBLIC:
* Indicates whether ExclusiveIsolatedClientSession should be created.
*/
public boolean isExclusive() {
return isExclusiveIsolated() || isExclusiveAlways();
}
/**
* PUBLIC:
* Return if a lazy connection should be used, a lazy connection only acquire a physical connection
* when a transaction is started and releases the connection when the transaction completes.
*/
public boolean isLazy() {
return isLazy;
}
/**
* INTERNAL:
* Return if part of a connection pool.
*/
public boolean isPooled() {
return poolName != null;
}
/**
* INTERNAL:
* Return if part of a connection pool.
*/
public boolean isUserDefinedConnection() {
return poolName == null;
}
/**
* PUBLIC:
* This method is used to remove a custom property from the Connection Policy.
* This method will return the propery removed. If it was not found then null
* will be returned.
*/
public Object removeProperty(Object key) {
if (this.hasProperties()) {
return getProperties().remove(key);
}
return null;
}
/**
* PUBLIC:
* Set if a lazy connection should be used, a lazy connection only acquire a physical connection
* when a transaction is started and releases the connection when the transaction completes.
*/
public void setIsLazy(boolean isLazy) {
this.isLazy = isLazy;
}
/**
* PUBLIC:
* Set the login to use for this connection.
* Client sessions support using a separate user login for database modification.
* Pooled connections must use the pool's login and cannot define their own.
*/
public void setLogin(Login login) {
this.login = login;
}
/**
* PUBLIC:
* Set the pool name or null if not part of a pool.
*/
public void setPoolName(String poolName) {
this.poolName = poolName;
}
/**
* PUBLIC:
* Use this method to set custom properties on the Connection Policy. These
* properties will be available from within connection events but have no
* effect on the connection directly.
*/
public void setProperty(Object key, Object property) {
getProperties().put(key, property);
}
/**
* PUBLIC:
* Returns exclusive mode.
*/
public ExclusiveMode getExclusiveMode() {
return exclusiveMode;
}
/**
* PUBLIC:
* Sets exclusive mode, if null is passed sets the default value.
*/
public void setExclusiveMode(ExclusiveMode exclusiveMode) {
if(exclusiveMode == null) {
this.exclusiveMode = ExclusiveMode.Transactional;
} else {
this.exclusiveMode = exclusiveMode;
}
}
/**
* INTERNAL:
* return a string representation of this ConnectionPolicy
*/
@Override
public String toString() {
String type = "";
if (isPooled()) {
type = "(" + ToStringLocalization.buildMessage("pooled", null) + ": " + getPoolName();
} else {
type = "(" + ToStringLocalization.buildMessage("login", null) + ": " + getLogin();
}
if (isLazy()) {
type = type + "," + ToStringLocalization.buildMessage("lazy", null) + ")";
} else {
type = type + "," + ToStringLocalization.buildMessage("non-lazy", null) + ")";
}
return Helper.getShortClassName(getClass()) + type;
}
/**
* PUBLIC:
* A lazy connection only acquires a physical connection
* when a transaction is started and releases the connection when the transaction completes.
*/
public void useLazyConnection() {
setIsLazy(true);
}
}