org.nuiton.jaxx.runtime.application.DefaultApplicationContext Maven / Gradle / Ivy
package org.nuiton.jaxx.runtime.application;
/*-
* #%L
* JAXX :: Runtime
* %%
* Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.nuiton.jaxx.runtime.JAXXContext;
import org.nuiton.jaxx.runtime.context.DefaultJAXXContext;
import org.nuiton.jaxx.runtime.context.JAXXContextEntryDef;
import org.nuiton.jaxx.runtime.context.JAXXInitialContext;
import org.nuiton.jaxx.runtime.swing.session.SwingSessionHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* Application context (only one instance should exists and it is initialized by the {@link ApplicationBoot}.
*
* Created by tchemit on 26/01/2018.
*
* @author Tony Chemit - [email protected]
*/
public abstract class DefaultApplicationContext> implements ApplicationContext {
private static final Logger log = LogManager.getLogger(DefaultApplicationContext.class);
private static final JAXXContextEntryDef ENTRY = new JAXXContextEntryDef<>("ApplicationContext", DefaultApplicationContext.class);
private final ImmutableMap> components;
private final ImmutableMap> variables;
private final JAXXContext delegate;
private final ApplicationBoot boot;
private final Config config;
private final Object lock;
protected DefaultApplicationContext(ApplicationBoot boot,
Config config,
List> components,
List> variables) {
this.boot = Objects.requireNonNull(boot);
this.config = Objects.requireNonNull(config);
this.components = Maps.uniqueIndex(Objects.requireNonNull(components), ApplicationContextComponent::getName);
this.variables = Maps.uniqueIndex(Objects.requireNonNull(variables), ApplicationContextComponent::getName);
this.lock = new Object();
this.delegate = new DefaultJAXXContext();
}
protected static > ApplicationContextComponent SWING_SESSION_HELPER() {
return new ApplicationContextComponent(SwingSessionHelper.class) {
@Override
public SwingSessionHelper load(Context context, Config config) {
return new SwingSessionHelper(config.getSwingSessionFile());
}
};
}
/**
* Install the application into the given {@code context}.
*
* @param context where to install application context
*/
public final void install(JAXXContext context) {
ENTRY.setContextValue(context, this);
}
/**
* @return a new initial context within this application context.
*/
public final JAXXInitialContext toInitialContext() {
return new JAXXInitialContext().add(ENTRY, this);
}
@Override
public final ApplicationBoot getBoot() {
return boot;
}
@Override
public final Config getConfig() {
return config;
}
@Override
public final boolean isClosed() {
return getBoot().isClosed();
}
@Override
public final void setContextValue(T t) {
delegate.setContextValue(t);
}
@Override
public final void setContextValue(T t, String s) {
delegate.setContextValue(t, s);
}
@Override
public final void removeContextValue(Class aClass) {
delegate.removeContextValue(aClass);
}
@Override
public final void removeContextValue(Class aClass, String s) {
delegate.removeContextValue(aClass, s);
}
@Override
public final T getContextValue(Class aClass) {
return delegate.getContextValue(aClass);
}
@Override
public final T getContextValue(Class aClass, String s) {
return delegate.getContextValue(aClass, s);
}
@Override
public final void lock() throws InterruptedException {
synchronized (lock) {
lock.wait();
}
}
@Override
public final void unlock() {
synchronized (lock) {
lock.notifyAll();
}
}
@Override
public final List> components() {
return new ArrayList<>(components.values());
}
@Override
public final List> variables() {
return new ArrayList<>(variables.values());
}
@Override
public final void close() {
log.info(String.format("%s Closing application context: %s", ApplicationBoot.BOOT_LOG_PREFIX, this));
removeComponents(variables());
List> components = components();
// always removed components in reverse order
Collections.reverse(components);
removeComponents(components);
}
@Override
public final void addAction(String actionLabel, Runnable action) {
getBoot().addAction(actionLabel, action);
}
private void removeComponents(List> components) {
for (ApplicationContextComponent component : components) {
log.info(String.format("%s Removing %s", ApplicationBoot.BOOT_LOG_PREFIX, component));
try {
Object value = component.remove();
log.info(String.format("%s %s (%s) was removed.", ApplicationBoot.BOOT_LOG_PREFIX, component, value));
} catch (Exception e) {
// Never throw exception, closing must end
log.error(String.format("Can't remove %s: %s", component, e.getMessage()), e);
}
}
}
}