52n-wps-server-gcube/src/main/java/org/n52/wps/server/RepositoryManager.java

346 lines
12 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* • Apache License, version 2.0
* • Apache Software License, version 1.0
* • GNU Lesser General Public License, version 3
* • Mozilla Public License, versions 1.0, 1.1 and 2.0
* • Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* 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
* Public License for more details.
*/
package org.n52.wps.server;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.n52.wps.PropertyDocument.Property;
import org.n52.wps.RepositoryDocument.Repository;
import org.n52.wps.commons.WPSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Bastian Schaeffer, University of Muenster
*
*/
public class RepositoryManager {
private static RepositoryManager instance;
private static Logger LOGGER = LoggerFactory.getLogger(RepositoryManager.class);
private List<IAlgorithmRepository> repositories;
private ProcessIDRegistry globalProcessIDs = ProcessIDRegistry.getInstance();
private UpdateThread updateThread;
private RepositoryManager(){
// clear registry
globalProcessIDs.clearRegistry();
// initialize all Repositories
loadAllRepositories();
// FvK: added Property Change Listener support
// creates listener and register it to the wpsConfig instance.
WPSConfig.getInstance().addPropertyChangeListener(WPSConfig.WPSCONFIG_PROPERTY_EVENT_NAME, new PropertyChangeListener() {
public void propertyChange(
final PropertyChangeEvent propertyChangeEvent) {
LOGGER.info("Received Property Change Event: {}",
propertyChangeEvent.getPropertyName());
loadAllRepositories();
}
});
Double updateHours = WPSConfig.getInstance().getWPSConfig().getServer().getRepoReloadInterval();
if (updateHours != 0){
LOGGER.info("Setting repository update period to {} hours.", updateHours);
updateHours = updateHours * 3600 * 1000; // make milliseconds
long updateInterval = updateHours.longValue();
this.updateThread = new UpdateThread(updateInterval);
updateThread.start();
}
}
private void loadAllRepositories(){
repositories = new ArrayList<IAlgorithmRepository>();
LOGGER.debug("Loading all repositories: {} (doing a gc beforehand...)", repositories);
System.gc();
Repository[] repositoryList = WPSConfig.getInstance().getRegisterdAlgorithmRepositories();
for(Repository repository : repositoryList){
if(repository.getActive()==false){
continue;
}
String repositoryClassName = repository.getClassName();
try {
IAlgorithmRepository algorithmRepository = null;
Class repositoryClass = RepositoryManager.class.getClassLoader().loadClass(repositoryClassName);
Constructor[] constructors = repositoryClass.getConstructors();
for(Constructor constructor : constructors){
if(constructor.getParameterTypes().length==1 && constructor.getParameterTypes()[0].equals(String.class)){
Property[] properties = repository.getPropertyArray();
Property formatProperty = WPSConfig.getInstance().getPropertyForKey(properties, "supportedFormat");
String format = formatProperty.getStringValue();
algorithmRepository = (IAlgorithmRepository) repositoryClass.getConstructor(String.class).newInstance(format);
}else{
algorithmRepository = (IAlgorithmRepository) repositoryClass.newInstance();
}
}
repositories.add(algorithmRepository);
LOGGER.info("Algorithm Repository {} initialized", repositoryClassName);
} catch (InstantiationException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}", repositoryClassName);
} catch (IllegalAccessException e) {
//in case of an singleton
// try {
//
// IAlgorithmRepository algorithmRepository = (IAlgorithmRepository)RepositoryManager.class.getClassLoader().loadClass(repositoryClassName).getMethod("getInstance", new Class[0]).invoke(null, new Object[0]);
// repositories.add(algorithmRepository);
// } catch (IllegalArgumentException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (SecurityException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (IllegalAccessException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (InvocationTargetException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (NoSuchMethodException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (ClassNotFoundException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// }
LOGGER.warn("An error occured while registering AlgorithmRepository: {}", repositoryClassName);
} catch (ClassNotFoundException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (IllegalArgumentException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (SecurityException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (InvocationTargetException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (NoSuchMethodException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
}
}
}
public static RepositoryManager getInstance(){
if(instance==null){
instance = new RepositoryManager();
}
return instance;
}
/**
* Allows to reInitialize the RepositoryManager... This should not be called to often.
*
*/
public static void reInitialize() {
instance = new RepositoryManager();
}
/**
* Allows to reInitialize the Repositories
*
*/
protected void reloadRepositories() {
loadAllRepositories();
}
/**
* Methods looks for Algorithm in all Repositories.
* The first match is returned.
* If no match could be found, null is returned
*
* @param className
* @return IAlgorithm or null
* @throws Exception
*/
public IAlgorithm getAlgorithm(String className){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(className)){
return repository.getAlgorithm(className);
}
}
return null;
}
/**
*
* @return allAlgorithms
*/
public List<String> getAlgorithms(){
List<String> allAlgorithmNamesCollection = new ArrayList<String>();
for(IAlgorithmRepository repository : repositories){
allAlgorithmNamesCollection.addAll(repository.getAlgorithmNames());
}
return allAlgorithmNamesCollection;
}
public boolean containsAlgorithm(String algorithmName) {
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(algorithmName)){
return true;
}
}
return false;
}
public IAlgorithmRepository getRepositoryForAlgorithm(String algorithmName){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(algorithmName)){
return repository;
}
}
return null;
}
public Class getInputDataTypeForAlgorithm(String algorithmIdentifier, String inputIdentifier){
IAlgorithm algorithm = getAlgorithm(algorithmIdentifier);
return algorithm.getInputDataType(inputIdentifier);
}
public Class getOutputDataTypeForAlgorithm(String algorithmIdentifier, String inputIdentifier){
IAlgorithm algorithm = getAlgorithm(algorithmIdentifier);
return algorithm.getOutputDataType(inputIdentifier);
}
public boolean registerAlgorithm(String id, IAlgorithmRepository repository){
if (globalProcessIDs.addID(id)){
return true;
}
else return false;
}
public boolean unregisterAlgorithm(String id){
if (globalProcessIDs.removeID(id)){
return true;
}
else return false;
}
public IAlgorithmRepository getAlgorithmRepository(String name){
for (IAlgorithmRepository repo : repositories ){
if(repo.getClass().getName().equals(name)){
return repo;
}
}
return null;
}
public IAlgorithmRepository getRepositoryForClassName(
String className) {
for(IAlgorithmRepository repository : repositories){
if(repository.getClass().getName().equals(className)){
return repository;
}
}
return null;
}
public ProcessDescriptionType getProcessDescription(String processClassName){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(processClassName)){
return repository.getProcessDescription(processClassName);
}
}
return null;
}
static class UpdateThread extends Thread {
private final long interval;
private boolean firstrun = true;
public UpdateThread (long interval){
this.interval = interval;
}
@Override
public void run() {
LOGGER.debug("UpdateThread started");
try {
// never terminate the run method
while (true){
// do not update on first run!
if (!firstrun){
LOGGER.info("Reloading repositories - this might take a while ...");
long timestamp = System.currentTimeMillis();
RepositoryManager.getInstance().reloadRepositories();
LOGGER.info("Repositories reloaded - going to sleep. Took {} seconds.",
(System.currentTimeMillis() - timestamp) / 1000);
} else {
firstrun = false;
}
// sleep for a given INTERVAL
sleep(interval);
}
} catch (InterruptedException e) {
LOGGER.debug("Interrupt received - Terminating the UpdateThread.");
}
}
}
// shut down the update thread
public void finalize(){
if (updateThread != null){
updateThread.interrupt();
}
}
public void shutdown() {
LOGGER.debug("Shutting down all repositories..");
for (IAlgorithmRepository repo : repositories) {
repo.shutdown();
}
}
}