com.aspectran.core.service.DefaultCoreService Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2025 The Aspectran Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.aspectran.core.service;
import com.aspectran.core.component.Component;
import com.aspectran.core.context.ActivityContext;
import com.aspectran.core.context.builder.ActivityContextBuilder;
import com.aspectran.core.context.builder.ActivityContextBuilderException;
import com.aspectran.core.context.builder.HybridActivityContextBuilder;
import com.aspectran.core.context.config.AspectranConfig;
import com.aspectran.core.context.config.ContextConfig;
import com.aspectran.core.context.config.SystemConfig;
import com.aspectran.utils.Assert;
import com.aspectran.utils.FileLocker;
import com.aspectran.utils.InsufficientEnvironmentException;
import com.aspectran.utils.ShutdownHook;
import com.aspectran.utils.annotation.jsr305.NonNull;
import com.aspectran.utils.logging.Logger;
import com.aspectran.utils.logging.LoggerFactory;
/**
* The Class DefaultCoreService.
*/
public class DefaultCoreService extends AbstractCoreService {
private final Logger logger = LoggerFactory.getLogger(DefaultCoreService.class);
private FileLocker fileLocker;
private ShutdownHook.Manager shutdownHookManager;
/**
* Instantiates a new DefaultCoreService.
*/
public DefaultCoreService() {
super();
}
public DefaultCoreService(CoreService parentService, boolean derived) {
super(parentService, derived);
}
protected void configure(@NonNull AspectranConfig aspectranConfig) {
Assert.state(!isDerived(),
"Must not be called for derived services");
Assert.state(!hasActivityContextBuilder(),
"prepare() method can be called only once");
try {
setAspectranConfig(aspectranConfig);
SystemConfig systemConfig = aspectranConfig.getSystemConfig();
if (systemConfig != null) {
for (String key : systemConfig.getPropertyKeys()) {
String value = systemConfig.getProperty(key);
if (value != null) {
System.setProperty(key, value);
}
}
}
ContextConfig contextConfig = aspectranConfig.getContextConfig();
if (isRootService()) {
if (getBasePath() == null && contextConfig != null && contextConfig.hasBasePath()) {
setBasePath(contextConfig.getBasePath());
}
} else {
setBasePath(getParentService().getBasePath());
}
ActivityContextBuilder activityContextBuilder = new HybridActivityContextBuilder(this);
activityContextBuilder.configure(contextConfig);
setActivityContextBuilder(activityContextBuilder);
if (getBasePath() == null) {
setBasePath(activityContextBuilder.getBasePath());
}
if (isRootService() && contextConfig != null && contextConfig.isSingleton()) {
if (activityContextBuilder.hasOwnBasePath()) {
acquireSingletonLock();
} else {
logger.warn("Since no base directory is explicitly specified, no singleton lock is applied");
}
}
} catch (Exception e) {
throw new CoreServiceException("Unable to prepare the service", e);
}
}
protected void buildActivityContext() throws ActivityContextBuilderException {
Assert.state(getActivityContext() == null,
"ActivityContext is already built; " +
"Must destroy the current ActivityContext before reloading");
ActivityContext activityContext = getActivityContextBuilder().build();
setActivityContext(activityContext);
try {
((Component)activityContext).initialize();
} catch (Exception e) {
throw new ActivityContextBuilderException("Failed to initialize ActivityContext", e);
}
}
protected void destroyActivityContext() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying all cached resources...");
}
getActivityContextBuilder().destroy();
setActivityContext(null);
}
/**
* This method is executed immediately after the ActivityContext is loaded.
* @throws Exception if an error occurs
*/
protected void afterContextLoaded() throws Exception {
}
/**
* This method executed just before the ActivityContext is destroyed.
*/
protected void beforeContextDestroy() {
}
@Override
protected void doStart() throws Exception {
if (!isDerived()) {
buildActivityContext();
buildSchedulerService();
afterContextLoaded();
}
}
@Override
protected void doStop() {
if (!isDerived()) {
clearDerivedServices();
beforeContextDestroy();
destroyActivityContext();
}
}
@Override
public void start() throws Exception {
if (isRootService()) {
registerShutdownTask();
}
super.start();
}
@Override
public void stop() {
super.stop();
if (isRootService()) {
releaseSingletonLock();
removeShutdownTask();
getActivityContextBuilder().clear();
}
}
private void acquireSingletonLock() throws Exception {
Assert.state(fileLocker == null, "Singleton lock is already configured");
fileLocker = new FileLocker(getBasePath());
if (!fileLocker.lock()) {
throw new InsufficientEnvironmentException("Another instance of Aspectran is already " +
"running; Only one instance is allowed (context.singleton is set to true)");
}
}
private void releaseSingletonLock() {
if (fileLocker != null) {
try {
fileLocker.release();
fileLocker = null;
} catch (Exception e) {
logger.warn("Unable to release singleton lock: " + e);
}
}
}
/**
* Registers a shutdown hook with the JVM runtime, closing this context
* on JVM shutdown unless it has already been closed at that time.
*/
private void registerShutdownTask() {
shutdownHookManager = ShutdownHook.Manager.create(new ShutdownHook.Task() {
@Override
public void run() throws Exception {
if (isActive()) {
DefaultCoreService.super.stop();
releaseSingletonLock();
}
}
@Override
public String toString() {
return "Stop " + getServiceName();
}
});
}
/**
* De-registers a shutdown hook with the JVM runtime.
*/
private void removeShutdownTask() {
if (shutdownHookManager != null) {
shutdownHookManager.remove();
shutdownHookManager = null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy