001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.scheduling.commonj; 018 019import javax.naming.NamingException; 020 021import commonj.timers.TimerManager; 022 023import org.springframework.beans.factory.DisposableBean; 024import org.springframework.beans.factory.InitializingBean; 025import org.springframework.context.Lifecycle; 026import org.springframework.jndi.JndiLocatorSupport; 027import org.springframework.lang.Nullable; 028import org.springframework.util.Assert; 029 030/** 031 * Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager} 032 * Defines common configuration settings and common lifecycle handling. 033 * 034 * @author Juergen Hoeller 035 * @since 3.0 036 * @see commonj.timers.TimerManager 037 * @deprecated as of 5.1, in favor of EE 7's 038 * {@link org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler} 039 */ 040@Deprecated 041public abstract class TimerManagerAccessor extends JndiLocatorSupport 042 implements InitializingBean, DisposableBean, Lifecycle { 043 044 @Nullable 045 private TimerManager timerManager; 046 047 @Nullable 048 private String timerManagerName; 049 050 private boolean shared = false; 051 052 053 /** 054 * Specify the CommonJ TimerManager to delegate to. 055 * <p>Note that the given TimerManager's lifecycle will be managed 056 * by this FactoryBean. 057 * <p>Alternatively (and typically), you can specify the JNDI name 058 * of the target TimerManager. 059 * @see #setTimerManagerName 060 */ 061 public void setTimerManager(TimerManager timerManager) { 062 this.timerManager = timerManager; 063 } 064 065 /** 066 * Set the JNDI name of the CommonJ TimerManager. 067 * <p>This can either be a fully qualified JNDI name, or the JNDI name relative 068 * to the current environment naming context if "resourceRef" is set to "true". 069 * @see #setTimerManager 070 * @see #setResourceRef 071 */ 072 public void setTimerManagerName(String timerManagerName) { 073 this.timerManagerName = timerManagerName; 074 } 075 076 /** 077 * Specify whether the TimerManager obtained by this FactoryBean 078 * is a shared instance ("true") or an independent instance ("false"). 079 * The lifecycle of the former is supposed to be managed by the application 080 * server, while the lifecycle of the latter is up to the application. 081 * <p>Default is "false", i.e. managing an independent TimerManager instance. 082 * This is what the CommonJ specification suggests that application servers 083 * are supposed to offer via JNDI lookups, typically declared as a 084 * {@code resource-ref} of type {@code commonj.timers.TimerManager} 085 * in {@code web.xml}, with {@code res-sharing-scope} set to 'Unshareable'. 086 * <p>Switch this flag to "true" if you are obtaining a shared TimerManager, 087 * typically through specifying the JNDI location of a TimerManager that 088 * has been explicitly declared as 'Shareable'. Note that WebLogic's 089 * cluster-aware Job Scheduler is a shared TimerManager too. 090 * <p>The sole difference between this FactoryBean being in shared or 091 * non-shared mode is that it will only attempt to suspend / resume / stop 092 * the underlying TimerManager in case of an independent (non-shared) instance. 093 * This only affects the {@link org.springframework.context.Lifecycle} support 094 * as well as application context shutdown. 095 * @see #stop() 096 * @see #start() 097 * @see #destroy() 098 * @see commonj.timers.TimerManager 099 */ 100 public void setShared(boolean shared) { 101 this.shared = shared; 102 } 103 104 105 @Override 106 public void afterPropertiesSet() throws NamingException { 107 if (this.timerManager == null) { 108 if (this.timerManagerName == null) { 109 throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified"); 110 } 111 this.timerManager = lookup(this.timerManagerName, TimerManager.class); 112 } 113 } 114 115 /** 116 * Return the configured TimerManager, if any. 117 * @return the TimerManager, or {@code null} if not available 118 */ 119 @Nullable 120 protected final TimerManager getTimerManager() { 121 return this.timerManager; 122 } 123 124 /** 125 * Obtain the TimerManager for actual use. 126 * @return the TimerManager (never {@code null}) 127 * @throws IllegalStateException in case of no TimerManager set 128 * @since 5.0 129 */ 130 protected TimerManager obtainTimerManager() { 131 Assert.notNull(this.timerManager, "No TimerManager set"); 132 return this.timerManager; 133 } 134 135 136 //--------------------------------------------------------------------- 137 // Implementation of Lifecycle interface 138 //--------------------------------------------------------------------- 139 140 /** 141 * Resumes the underlying TimerManager (if not shared). 142 * @see commonj.timers.TimerManager#resume() 143 */ 144 @Override 145 public void start() { 146 if (!this.shared) { 147 obtainTimerManager().resume(); 148 } 149 } 150 151 /** 152 * Suspends the underlying TimerManager (if not shared). 153 * @see commonj.timers.TimerManager#suspend() 154 */ 155 @Override 156 public void stop() { 157 if (!this.shared) { 158 obtainTimerManager().suspend(); 159 } 160 } 161 162 /** 163 * Considers the underlying TimerManager as running if it is 164 * neither suspending nor stopping. 165 * @see commonj.timers.TimerManager#isSuspending() 166 * @see commonj.timers.TimerManager#isStopping() 167 */ 168 @Override 169 public boolean isRunning() { 170 TimerManager tm = obtainTimerManager(); 171 return (!tm.isSuspending() && !tm.isStopping()); 172 } 173 174 175 //--------------------------------------------------------------------- 176 // Implementation of DisposableBean interface 177 //--------------------------------------------------------------------- 178 179 /** 180 * Stops the underlying TimerManager (if not shared). 181 * @see commonj.timers.TimerManager#stop() 182 */ 183 @Override 184 public void destroy() { 185 // Stop the entire TimerManager, if necessary. 186 if (this.timerManager != null && !this.shared) { 187 // May return early, but at least we already cancelled all known Timers. 188 this.timerManager.stop(); 189 } 190 } 191 192}