001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2018 microBean. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 014 * implied. See the License for the specific language governing 015 * permissions and limitations under the License. 016 */ 017package org.microbean.jpa.org.eclipse.persistence.platform.server.cdi; 018 019import java.util.concurrent.Executor; 020 021import javax.enterprise.inject.Instance; 022 023import javax.enterprise.inject.spi.CDI; 024 025import javax.management.MBeanServer; 026 027import javax.transaction.TransactionManager; 028 029import org.eclipse.persistence.platform.server.JMXServerPlatformBase; 030 031import org.eclipse.persistence.sessions.DatabaseSession; 032import org.eclipse.persistence.sessions.JNDIConnector; 033 034import org.eclipse.persistence.transaction.JTATransactionController; 035 036/** 037 * A {@link JMXServerPlatformBase} that arranges things such that CDI, 038 * not JNDI, will be used to acquire a {@link TransactionManager} and 039 * {@link MBeanServer}. 040 * 041 * @author <a href="https://about.me/lairdnelson" 042 * target="_parent">Laird Nelson</a> 043 * 044 * @see #getExternalTransactionControllerClass() 045 */ 046public class CDISEPlatform extends JMXServerPlatformBase { 047 048 049 /* 050 * Instance fields. 051 */ 052 053 054 private final Executor executor; 055 056 private volatile Instance<MBeanServer> mBeanServerInstance; 057 058 059 /* 060 * Constructors. 061 */ 062 063 064 /** 065 * Creates a {@link CDISEPlatform}. 066 * 067 * @param session the {@link DatabaseSession} this platform will 068 * wrap; must not be {@code null} 069 * 070 * @see JMXServerPlatformBase#JMXServerPlatformBase(DatabaseSession) 071 */ 072 public CDISEPlatform(final DatabaseSession session) { 073 super(session); 074 final CDI<Object> cdi = CDI.current(); 075 assert cdi != null; 076 if (!cdi.select(TransactionManager.class).isResolvable()) { 077 this.disableJTA(); 078 } 079 final Instance<Executor> executorInstance = cdi.select(Executor.class); 080 if (executorInstance == null || !executorInstance.isResolvable()) { 081 this.executor = null; 082 } else { 083 this.executor = executorInstance.get(); 084 } 085 } 086 087 088 /* 089 * Instance methods. 090 */ 091 092 093 @Override 094 public boolean isRuntimeServicesEnabledDefault() { 095 Instance<MBeanServer> instance = this.mBeanServerInstance; 096 final boolean returnValue; 097 if (instance == null) { 098 instance = CDI.current().select(MBeanServer.class); 099 assert instance != null; 100 if (instance.isResolvable()) { 101 this.mBeanServerInstance = instance; 102 returnValue = true; 103 } else { 104 returnValue = false; 105 } 106 } else { 107 returnValue = instance.isResolvable(); 108 } 109 return returnValue; 110 } 111 112 @Override 113 public MBeanServer getMBeanServer() { 114 if (this.mBeanServer == null) { 115 final Instance<MBeanServer> instance = this.mBeanServerInstance; 116 if (instance != null && instance.isResolvable()) { 117 this.mBeanServer = instance.get(); 118 } 119 } 120 return super.getMBeanServer(); 121 } 122 123 @Override 124 public void launchContainerRunnable(final Runnable runnable) { 125 if (runnable != null && this.executor != null) { 126 this.executor.execute(runnable); 127 } else { 128 super.launchContainerRunnable(runnable); 129 } 130 } 131 132 /** 133 * Returns a non-{@code null} {@link Class} that extends {@link 134 * org.eclipse.persistence.transaction.AbstractTransactionController}. 135 * 136 * @return a non-{@code null} {@link Class} that extends {@link 137 * org.eclipse.persistence.transaction.AbstractTransactionController} 138 * 139 * @see org.eclipse.persistence.transaction.AbstractTransactionController 140 */ 141 @Override 142 public final Class<?> getExternalTransactionControllerClass() { 143 if (this.externalTransactionControllerClass == null) { 144 this.externalTransactionControllerClass = TransactionController.class; 145 } 146 return this.externalTransactionControllerClass; 147 } 148 149 /** 150 * Returns {@link JNDIConnector#UNDEFINED_LOOKUP} when invoked. 151 * 152 * @return {@link JNDIConnector#UNDEFINED_LOOKUP} 153 */ 154 @Override 155 public final int getJNDIConnectorLookupType() { 156 return JNDIConnector.UNDEFINED_LOOKUP; 157 } 158 159 160 /* 161 * Inner and nested classes. 162 */ 163 164 165 /** 166 * A {@link JTATransactionController} whose {@link 167 * #acquireTransactionManager()} uses CDI, not JNDI, to return a 168 * {@link TransactionManager} instance. 169 * 170 * @author <a href="https://about.me/lairdnelson" 171 * target="_parent">Laird Nelson</a> 172 * 173 * @see #acquireTransactionManager() 174 * 175 * @see JTATransactionController 176 */ 177 public static final class TransactionController extends JTATransactionController { 178 179 180 /* 181 * Constructors. 182 */ 183 184 185 /** 186 * Creates a new {@link TransactionController}. 187 */ 188 public TransactionController() { 189 super(); 190 } 191 192 193 /* 194 * Instance methods. 195 */ 196 197 198 /** 199 * Returns a non-{@code null} {@link TransactionManager}. 200 * 201 * @return a non-{@code null} {@link TransactionManager} 202 */ 203 @Override 204 protected final TransactionManager acquireTransactionManager() { 205 return CDI.current().select(TransactionManager.class).get(); 206 } 207 208 } 209 210}