
org.echocat.jomon.process.daemon.ProcessDaemonRepository Maven / Gradle / Ivy
/*****************************************************************************************
* *** BEGIN LICENSE BLOCK *****
*
* Version: MPL 2.0
*
* echocat Jomon, Copyright (c) 2012-2013 echocat
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* *** END LICENSE BLOCK *****
****************************************************************************************/
package org.echocat.jomon.process.daemon;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.echocat.jomon.process.CouldNotStartException;
import org.echocat.jomon.process.GeneratedProcess;
import org.echocat.jomon.runtime.CollectionUtils;
import org.echocat.jomon.runtime.generation.Generator;
import org.echocat.jomon.runtime.iterators.CloseableIterator;
import org.echocat.jomon.runtime.repository.InsertingRepository;
import org.echocat.jomon.runtime.repository.QueryableRepository;
import org.echocat.jomon.runtime.repository.RemovingRepository;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Collections.sort;
import static org.echocat.jomon.runtime.CollectionUtils.*;
import static org.echocat.jomon.runtime.iterators.IteratorUtils.filter;
import static org.echocat.jomon.runtime.util.ResourceUtils.closeQuietly;
@ThreadSafe
public class ProcessDaemonRepository<
E,
ID,
P extends GeneratedProcess,
D extends ProcessDaemon,
R extends ProcessDaemonRequirement,
Q extends BaseProcessDaemonQuery,
G extends Generator
> implements QueryableRepository, Iterable, RemovingRepository, InsertingRepository, Generator, AutoCloseable {
@Nonnull
private static final Comparator> BY_PARAMETER_COUNT = new Comparator>() { @Override public int compare(Constructor> o1, Constructor> o2) {
return Integer.compare(o2.getParameterTypes().length, o1.getParameterTypes().length);
}};
@Nonnull
private final Thread _shutdownHook = new Thread("ShutdownProcessDaemons") { @Override public void run() {
close();
}};
@Nonnull
private final Map _idToProcess = new ConcurrentHashMap<>();
@Nonnull
private final G _processGenerator;
public ProcessDaemonRepository(@Nonnull G processGenerator) {
_processGenerator = processGenerator;
Runtime.getRuntime().addShutdownHook(_shutdownHook);
}
@Nonnull
@Override
public D generate(@Nonnull R requirement) {
final D daemon = createInstanceFor(requirement);
_idToProcess.put(daemon.getProcess().getId(), daemon);
return daemon;
}
@Override
public void insert(@Nonnull D daemon) {
_idToProcess.put(daemon.getProcess().getId(), daemon);
}
@Nullable
@Override
public D findOneBy(@Nonnull ID id) {
return _idToProcess.get(id);
}
@Nullable
@Override
public D findOneBy(@Nonnull Q query) {
return findFirstOf(findBy(query));
}
@Nonnull
@Override
public CloseableIterator findBy(@Nonnull Q query) {
return filter(iterator(), query);
}
@Override
public long countBy(@Nonnull Q query) {
return countElementsOf(iterator(), query);
}
@Override
public boolean removeBy(@Nonnull ID id) {
final D daemon = _idToProcess.remove(id);
if (daemon != null) {
closeQuietly(daemon);
}
return daemon != null;
}
@Override
public long removeBy(@Nonnull Q query) {
long removed = 0;
try (final CloseableIterator i = findBy(query)) {
while (i.hasNext()) {
final D daemon = i.next();
final ID id = daemon.getProcess().getId();
if (_idToProcess.remove(id) != null) {
closeQuietly(daemon);
removed++;
}
}
}
return removed;
}
@Nonnull
protected Collection getCopySafe() {
synchronized (_idToProcess) {
return new HashSet<>(_idToProcess.values());
}
}
@Override
public Iterator iterator() {
return getCopySafe().iterator();
}
@Nonnull
protected Pair, Object[]> getConstructorFor(@Nonnull R requirement) {
return getConstructorFor(requirement.getType(), requirement);
}
@Nonnull
protected Pair, Object[]> getConstructorFor(@Nonnull Class type, @Nonnull R requirement) {
final List