org.glassfish.ejb.deployment.descriptor.EjbSessionDescriptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates]
package org.glassfish.ejb.deployment.descriptor;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.LifecycleCallbackDescriptor;
import com.sun.enterprise.deployment.MethodDescriptor;
import com.sun.enterprise.deployment.util.TypeUtil;
import com.sun.enterprise.util.LocalStringManagerImpl;
import fish.payara.cluster.DistributedLockType;
import org.glassfish.internal.api.Globals;
import org.glassfish.internal.deployment.AnnotationTypesProvider;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Objects of this kind represent the deployment information describing a single
* Session Ejb : { stateful , stateless, singleton }
*@author Danny Coward
*/
public class EjbSessionDescriptor extends EjbDescriptor
implements com.sun.enterprise.deployment.EjbSessionDescriptor {
private Set postActivateDescs =
new HashSet();
private Set prePassivateDescs =
new HashSet();
// For EJB 3.0 stateful session beans, information about the assocation
// between a business method and bean removal.
private Map removeMethods
= new HashMap();
// For EJB 3.0 stateful session beans with adapted homes, list of
// business methods corresponding to Home/LocalHome create methods.
private Set initMethods=new HashSet();
private MethodDescriptor afterBeginMethod = null;
private MethodDescriptor beforeCompletionMethod = null;
private MethodDescriptor afterCompletionMethod = null;
// Holds @StatefulTimeout or stateful-timeout from
// ejb-jar.xml. Only applies to stateful session beans.
// Initialize to "not set"(null) state so annotation processing
// can apply the correct overriding behavior.
private Long statefulTimeoutValue = null;
private TimeUnit statefulTimeoutUnit;
private boolean sessionTypeIsSet = false;
private boolean isStateless = false;
private boolean isStateful = false;
private boolean isSingleton = false;
// ejb3.2 spec 4.6.5 Disabling Passivation of Stateful Session Beans
private boolean isPassivationCapable = true;
private boolean passivationCapableIsSet = false;
private boolean clustered = false;
private boolean dontCallPostConstructOnAttach = false;
private boolean dontCallPreDestroyOnDetach = false;
private String clusteredKeyValue = "";
private DistributedLockType clusteredLockType = DistributedLockType.INHERIT;
private List readLockMethods = new ArrayList();
private List writeLockMethods = new ArrayList();
private List accessTimeoutMethods =
new ArrayList();
private List asyncMethods = new ArrayList();
// Controls eager vs. lazy Singleton initialization
private Boolean initOnStartup = null;
private static final String[] _emptyDepends = new String[] {};
private String[] dependsOn = _emptyDepends;
private ConcurrencyManagementType concurrencyManagementType;
private static LocalStringManagerImpl localStrings =
new LocalStringManagerImpl(EjbSessionDescriptor.class);
/**
* Default constructor.
*/
public EjbSessionDescriptor() {
}
@Override
public String getEjbTypeForDisplay() {
if (isStateful()) {
return "StatefulSessionBean";
} else if (isStateless()) {
return "StatelessSessionBean";
} else {
return "SingletonSessionBean";
}
}
public boolean isPassivationCapable() {
return isPassivationCapable;
}
public void setPassivationCapable(boolean passivationCapable) {
isPassivationCapable = passivationCapable;
passivationCapableIsSet = true;
}
public boolean isPassivationCapableSet() {
return passivationCapableIsSet;
}
/**
* Returns the type of this bean - always "Session".
*/
public String getType() {
return TYPE;
}
/**
* Returns the string STATELESS or STATEFUL according as to whether
* the bean is stateless or stateful.
**/
public String getSessionType() {
if (this.isStateless()) {
return STATELESS;
} else if( isStateful() ){
return STATEFUL;
} else {
return SINGLETON;
}
}
/**
* Accepts the Strings STATELESS / STATEFUL / SINGLETON
*/
public void setSessionType(String sessionType) {
if (STATELESS.equals(sessionType)) {
isStateless = true;
} else if(STATEFUL.equals(sessionType)) {
isStateful = true;
} else if(SINGLETON.equals(sessionType)){
isSingleton = true;
} else {
if (this.isBoundsChecking()) {
throw new IllegalArgumentException(localStrings.getLocalString(
"enterprise.deployment.exceptionsessiontypenotlegaltype",
"{0} is not a legal session type for session ejbs. The type must be {1} or {2}",
new Object[] {sessionType, STATEFUL, STATELESS}));
}
}
sessionTypeIsSet = true;
return;
}
/**
* Useful for certain annotation / .xml processing. ejb-jar.xml might
* not set if it's only being used for sparse overriding.
* @return
*/
public boolean isSessionTypeSet() {
return sessionTypeIsSet;
}
@Override
public boolean isClustered() {
return clustered;
}
public void setClustered(boolean clustered) {
this.clustered = clustered;
}
@Override
public String getClusteredKeyValue() {
return clusteredKeyValue;
}
public void setClusteredKeyValue(String clusteredKeyValue) {
this.clusteredKeyValue = clusteredKeyValue;
}
@Override
public DistributedLockType getClusteredLockType() {
return clusteredLockType;
}
public void setClusteredLockType(DistributedLockType lockType) {
this.clusteredLockType = lockType;
}
public boolean dontCallPostConstructOnAttach() {
return dontCallPostConstructOnAttach;
}
public void setDontCallPostConstructOnAttach(boolean dontCallPostConstructOnAttach) {
this.dontCallPostConstructOnAttach = dontCallPostConstructOnAttach;
}
public void setDontCallPreDestroyOnDetach(boolean dontCallPreDestroyOnDetach) {
this.dontCallPreDestroyOnDetach = dontCallPreDestroyOnDetach;
}
public boolean dontCallPreDestroyOnDetach() {
return dontCallPreDestroyOnDetach;
}
/**
* Sets my type
*/
public void setType(String type) {
throw new IllegalArgumentException(localStrings.getLocalString(
"enterprise.deployment.exceptioncannotsettypeofsessionbean",
"Cannot set the type of a session bean"));
}
/**
* Sets the transaction type for this bean. Must be either BEAN_TRANSACTION_TYPE or CONTAINER_TRANSACTION_TYPE.
*/
public void setTransactionType(String transactionType) {
boolean isValidType = (BEAN_TRANSACTION_TYPE.equals(transactionType) ||
CONTAINER_TRANSACTION_TYPE.equals(transactionType));
if (!isValidType && this.isBoundsChecking()) {
throw new IllegalArgumentException(localStrings.getLocalString(
"enterprise.deployment..exceptointxtypenotlegaltype",
"{0} is not a legal transaction type for session beans", new Object[] {transactionType}));
} else {
super.transactionType = transactionType;
super.setMethodContainerTransactions(new Hashtable());
}
}
/**
* Returns true if I am describing a stateless session bean.
*/
public boolean isStateless() {
return isStateless;
}
public boolean isStateful() {
return isStateful;
}
public boolean isSingleton() {
return isSingleton;
}
public boolean hasAsynchronousMethods() {
return (asyncMethods.size() > 0);
}
public void addAsynchronousMethod(MethodDescriptor m) {
asyncMethods.add(m);
}
public List getAsynchronousMethods() {
return new ArrayList(asyncMethods);
}
public boolean isAsynchronousMethod(Method m) {
boolean async = false;
for(MethodDescriptor next : asyncMethods) {
Method nextMethod = next.getMethod(this);
if( (nextMethod != null) &&
TypeUtil.sameMethodSignature(m, nextMethod)) {
async = true;
break;
}
}
return async;
}
public void addStatefulTimeoutDescriptor(TimeoutValueDescriptor timeout) {
statefulTimeoutValue = timeout.getValue();
statefulTimeoutUnit = timeout.getUnit();
}
public void setStatefulTimeout(Long value, TimeUnit unit) {
statefulTimeoutValue = value;
statefulTimeoutUnit = unit;
}
public boolean hasStatefulTimeout() {
return (statefulTimeoutValue != null);
}
public Long getStatefulTimeoutValue() {
return statefulTimeoutValue;
}
public TimeUnit getStatefulTimeoutUnit() {
return statefulTimeoutUnit;
}
public boolean hasRemoveMethods() {
return (!removeMethods.isEmpty());
}
/**
* @return remove method info for the given method or null if the
* given method is not a remove method for this stateful session bean.
*/
public EjbRemovalInfo getRemovalInfo(MethodDescriptor method) {
// first try to find the exact match
for (Map.Entry entry : removeMethods.entrySet()) {
MethodDescriptor methodDesc = entry.getKey();
if (methodDesc.equals(method)) {
return entry.getValue();
}
}
// if nothing is found, try to find the loose match
for (Map.Entry entry : removeMethods.entrySet()) {
MethodDescriptor methodDesc = entry.getKey();
if (methodDesc.implies(method)) {
return entry.getValue();
}
}
return null;
}
public Set getAllRemovalInfo() {
return new HashSet(removeMethods.values());
}
// FIXME by srini - validate changing CDI code to use this is fine
@Override
public Set getRemoveMethodDescriptors() {
return new HashSet(removeMethods.keySet());
}
public void addRemoveMethod(EjbRemovalInfo removalInfo) {
removeMethods.put(removalInfo.getRemoveMethod(), removalInfo);
}
public boolean hasInitMethods() {
return (!initMethods.isEmpty());
}
public Set getInitMethods() {
return new HashSet(initMethods);
}
public void addInitMethod(EjbInitInfo initInfo) {
initMethods.add(initInfo);
}
public Set getPostActivateDescriptors() {
if (postActivateDescs == null) {
postActivateDescs =
new HashSet();
}
return postActivateDescs;
}
public void addPostActivateDescriptor(LifecycleCallbackDescriptor
postActivateDesc) {
String className = postActivateDesc.getLifecycleCallbackClass();
boolean found = false;
for (LifecycleCallbackDescriptor next :
getPostActivateDescriptors()) {
if (next.getLifecycleCallbackClass().equals(className)) {
found = true;
break;
}
}
if (!found) {
getPostActivateDescriptors().add(postActivateDesc);
}
}
public LifecycleCallbackDescriptor
getPostActivateDescriptorByClass(String className) {
for (LifecycleCallbackDescriptor next :
getPostActivateDescriptors()) {
if (next.getLifecycleCallbackClass().equals(className)) {
return next;
}
}
return null;
}
public boolean hasPostActivateMethod() {
return (getPostActivateDescriptors().size() > 0);
}
public Set getPrePassivateDescriptors() {
if (prePassivateDescs == null) {
prePassivateDescs =
new HashSet();
}
return prePassivateDescs;
}
public void addPrePassivateDescriptor(LifecycleCallbackDescriptor
prePassivateDesc) {
String className = prePassivateDesc.getLifecycleCallbackClass();
boolean found = false;
for (LifecycleCallbackDescriptor next :
getPrePassivateDescriptors()) {
if (next.getLifecycleCallbackClass().equals(className)) {
found = true;
break;
}
}
if (!found) {
getPrePassivateDescriptors().add(prePassivateDesc);
}
}
public LifecycleCallbackDescriptor
getPrePassivateDescriptorByClass(String className) {
for (LifecycleCallbackDescriptor next :
getPrePassivateDescriptors()) {
if (next.getLifecycleCallbackClass().equals(className)) {
return next;
}
}
return null;
}
public boolean hasPrePassivateMethod() {
return (getPrePassivateDescriptors().size() > 0);
}
public Vector getPossibleTransactionAttributes() {
Vector txAttributes = super.getPossibleTransactionAttributes();
// Session beans that implement SessionSynchronization interface
// have a limited set of possible transaction attributes.
if( isStateful() ) {
try {
EjbBundleDescriptorImpl ejbBundle = getEjbBundleDescriptor();
ClassLoader classLoader = ejbBundle.getClassLoader();
Class ejbClass = classLoader.loadClass(getEjbClassName());
AnnotationTypesProvider provider = Globals.getDefaultHabitat().getService(AnnotationTypesProvider.class, "EJB");
if (provider!=null) {
Class sessionSynchClass = provider.getType("jakarta.ejb.SessionSynchronization");
if( sessionSynchClass.isAssignableFrom(ejbClass) ) {
txAttributes = new Vector();
txAttributes.add(new ContainerTransaction
(ContainerTransaction.REQUIRED, ""));
txAttributes.add(new ContainerTransaction
(ContainerTransaction.REQUIRES_NEW, ""));
txAttributes.add(new ContainerTransaction
(ContainerTransaction.MANDATORY, ""));
}
}
} catch(Exception e) {
// Don't treat this as a fatal error. Just return full
// set of possible transaction attributes.
}
}
return txAttributes;
}
@Override
public String getContainerFactoryQualifier() {
if(isStateful)
return "StatefulContainerFactory";
if(isStateless)
return "StatelessContainerFactory";
return "SingletonContainerFactory";
}
public void addAfterBeginDescriptor(MethodDescriptor m) {
afterBeginMethod = m;
}
public void addBeforeCompletionDescriptor(MethodDescriptor m) {
beforeCompletionMethod = m;
}
public void addAfterCompletionDescriptor(MethodDescriptor m) {
afterCompletionMethod = m;
}
/**
* Set the Method annotated @AfterBegin.
*/
public void setAfterBeginMethodIfNotSet(MethodDescriptor m) {
if( afterBeginMethod == null) {
afterBeginMethod = m;
}
}
/**
* Returns the Method annotated @AfterBegin.
*/
public MethodDescriptor getAfterBeginMethod() {
return afterBeginMethod;
}
/**
* Set the Method annotated @BeforeCompletion.
*/
public void setBeforeCompletionMethodIfNotSet(MethodDescriptor m) {
if( beforeCompletionMethod == null ) {
beforeCompletionMethod = m;
}
}
/**
* Returns the Method annotated @AfterBegin.
*/
public MethodDescriptor getBeforeCompletionMethod() {
return beforeCompletionMethod;
}
/**
* Set the Method annotated @AfterCompletion.
*/
public void setAfterCompletionMethodIfNotSet(MethodDescriptor m) {
if( afterCompletionMethod == null ) {
afterCompletionMethod = m;
}
}
/**
* Returns the Method annotated @AfterCompletion.
*/
public MethodDescriptor getAfterCompletionMethod() {
return afterCompletionMethod;
}
public boolean getInitOnStartup() {
return ( (initOnStartup != null) && initOnStartup );
}
public void setInitOnStartup(boolean flag) {
initOnStartup = flag;
}
public void setInitOnStartupIfNotAlreadySet(boolean flag) {
if( initOnStartup == null ) {
setInitOnStartup(flag);
}
}
public String[] getDependsOn() {
return dependsOn;
}
public boolean hasDependsOn() {
return (dependsOn.length > 0);
}
public void setDependsOn(String[] dep) {
dependsOn = (dep == null) ? _emptyDepends : dep;
}
public void setDependsOnIfNotSet(String[] dep) {
if( !hasDependsOn() ) {
setDependsOn(dep);
}
}
public ConcurrencyManagementType getConcurrencyManagementType() {
return (concurrencyManagementType != null) ? concurrencyManagementType :
ConcurrencyManagementType.Container;
}
public boolean hasContainerManagedConcurrency() {
return (getConcurrencyManagementType() == ConcurrencyManagementType.Container);
}
public boolean hasBeanManagedConcurrency() {
return (getConcurrencyManagementType() == ConcurrencyManagementType.Bean);
}
public void setConcurrencyManagementType(ConcurrencyManagementType type) {
concurrencyManagementType = type;
}
public void setConcurrencyManagementTypeIfNotSet(ConcurrencyManagementType type) {
if( concurrencyManagementType == null) {
setConcurrencyManagementType(type);
}
}
public void addConcurrentMethodFromXml(ConcurrentMethodDescriptor concMethod) {
// .xml must contain a method. However, both READ/WRITE lock metadata
// and access timeout are optional.
MethodDescriptor methodDesc = concMethod.getConcurrentMethod();
if( concMethod.hasLockMetadata()) {
if( concMethod.isWriteLocked()) {
addWriteLockMethod(methodDesc);
} else {
addReadLockMethod(methodDesc);
}
}
if( concMethod.hasAccessTimeout() ) {
this.addAccessTimeoutMethod(methodDesc, concMethod.getAccessTimeoutValue(),
concMethod.getAccessTimeoutUnit());
}
}
public void addReadLockMethod(MethodDescriptor methodDescriptor) {
readLockMethods.add(methodDescriptor);
}
public void addWriteLockMethod(MethodDescriptor methodDescriptor) {
writeLockMethods.add(methodDescriptor);
}
public List getReadLockMethods() {
return new ArrayList(readLockMethods);
}
public List getWriteLockMethods() {
return new ArrayList(writeLockMethods);
}
public List getReadAndWriteLockMethods() {
List readAndWriteLockMethods = new ArrayList();
readAndWriteLockMethods.addAll(readLockMethods);
readAndWriteLockMethods.addAll(writeLockMethods);
return readAndWriteLockMethods;
}
public void addAccessTimeoutMethod(MethodDescriptor methodDescriptor, long value,
TimeUnit unit) {
accessTimeoutMethods.add(new AccessTimeoutHolder(value, unit, methodDescriptor));
}
public List getAccessTimeoutMethods() {
List methods = new ArrayList();
for(AccessTimeoutHolder holder : accessTimeoutMethods){
methods.add(holder.method);
}
return methods;
}
public List getAccessTimeoutInfo() {
List all = new ArrayList();
for(AccessTimeoutHolder holder : accessTimeoutMethods){
all.add(holder);
}
return all;
}
/**
* Returns a formatted String of the attributes of this object.
*/
public void print(StringBuilder toStringBuilder) {
toStringBuilder.append("Session descriptor");
toStringBuilder.append("\n sessionType ").append(getSessionType());
super.print(toStringBuilder);
}
/**
* Return the fully-qualified portable JNDI name for a given
* client view (Remote, Local, or no-interface).
*/
public String getPortableJndiName(String clientViewType) {
String appName = null;
Application app = getEjbBundleDescriptor().getApplication();
if ( ! app.isVirtual() ) {
appName = app.getAppName();
}
String modName = getEjbBundleDescriptor().getModuleDescriptor().getModuleName();
StringBuilder javaGlobalPrefix = new StringBuilder("java:global/");
if (appName != null) {
javaGlobalPrefix.append(appName);
javaGlobalPrefix.append("/");
}
javaGlobalPrefix.append(modName);
javaGlobalPrefix.append("/");
javaGlobalPrefix.append(getName());
javaGlobalPrefix.append("!");
javaGlobalPrefix.append(clientViewType);
return javaGlobalPrefix.toString();
}
public static class AccessTimeoutHolder {
public AccessTimeoutHolder(long v, TimeUnit u, MethodDescriptor m) {
value = v;
unit = u;
method = m;
}
public long value;
public TimeUnit unit;
public MethodDescriptor method;
}
public enum ConcurrencyManagementType {
Bean,
Container,
}
}