/**
* Copyright (C) 2009 - 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.ags;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.UUID;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.n52.wps.PropertyDocument.Property;
import org.n52.wps.ags.algorithmpackage.AlgorithmPackage;
import org.n52.wps.commons.WPSConfig;
import org.n52.wps.server.IAlgorithm;
import org.n52.wps.server.IAlgorithmRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Matthias Mueller, TU Dresden
*
*/
public class ArcToolboxProcessRepository implements IAlgorithmRepository{
private static Logger LOGGER = LoggerFactory.getLogger(ArcToolboxProcessRepository.class);
private static final String PROPERTY_PROCESS_INVENTORY_DIR = "PROCESS_INVENTORY_DIR";
private static final String PROPERTY_CONTAINER_URN = "CONTAINER_URN";
private static final String PROPERTY_BACKEND_URN = "BACKEND_URN";
private static final String PROPERTY_WORKSPACEBASE = "WORKSPACEBASE";
private HashMap<String, AlgorithmPackage> registeredAlgorithms;
private URI[] supportedContainers;
private URI[] supportedBackends;
private File workspaceBase = null;
private File inventoryDir = null;
public ArcToolboxProcessRepository() {
LOGGER.info("Initializing ArcToolbox Process Repository ...");
//initialize local variables
registeredAlgorithms = new HashMap<String, AlgorithmPackage>();
try{
loadConfiguration();
loadLocalProcesses();
} catch (Exception e){
LOGGER.error("Could not initialize ArcToolbox Process Repository.");
}
// check if workspaceBase is specified
if (workspaceBase == null){
LOGGER.error("Workspace base is missing: Clearing my Process Inventory");
registeredAlgorithms = new HashMap<String, AlgorithmPackage>();
}
// log active Processes ...
LOGGER.info("Algorithms loaded by ArcToolbox Process Repository:");
for (String currentKey : registeredAlgorithms.keySet()){
LOGGER.info(currentKey);
}
// ... or state that there arent't any
if (registeredAlgorithms.size()==0){
LOGGER.info("No applicable algorithms fond");
}
}
private void loadConfiguration() throws Exception{
Property[] props = WPSConfig.getInstance().getPropertiesForRepositoryClass(this.getClass().getCanonicalName());
ArrayList<URI> containerList = new ArrayList<URI>();
ArrayList<URI> backendList = new ArrayList<URI>();
for(Property currentProp : props){
try{
if (currentProp.getActive()){
String propName = currentProp.getName();
if (propName.equalsIgnoreCase(PROPERTY_PROCESS_INVENTORY_DIR)){
inventoryDir = new File (currentProp.getStringValue());
}
if (propName.equalsIgnoreCase(PROPERTY_WORKSPACEBASE)){
workspaceBase = new File (currentProp.getStringValue());
}
if (propName.equalsIgnoreCase(PROPERTY_BACKEND_URN)){
backendList.add(new URI (currentProp.getStringValue()));
}
if (propName.equalsIgnoreCase(PROPERTY_CONTAINER_URN)){
containerList.add(new URI (currentProp.getStringValue()));
}
}
} catch (URISyntaxException e){
LOGGER.error("Invalid container or backend URN - offending item is " + currentProp.getStringValue());
}
}
supportedContainers = containerList.toArray(new URI[0]);
supportedBackends = backendList.toArray(new URI[0]);
containerList = null;
backendList = null;
}
private void loadLocalProcesses(){
// abort loading if inventoryDir is empty
if (inventoryDir == null){
return;
}
String[] describeProcessFiles = retrieveProcessDescriptions(inventoryDir);
// create new MovingCodeObjects
for (String currentFileName : describeProcessFiles){
File currentFile = new File (inventoryDir.getAbsolutePath() + File.separator + currentFileName);
AlgorithmPackage currentMCO = new AlgorithmPackage(currentFile, inventoryDir);
if (isSupportedScript(currentMCO)){
registeredAlgorithms.put(currentMCO.getProcessID(), currentMCO);
} else {
LOGGER.info(currentMCO.getProcessID() + " is not supported by this repository. - Dropping algorithm.");
currentMCO = null;
}
}
}
private boolean isSupportedScript(AlgorithmPackage mco){
boolean rightContainer = false;
boolean rightBackends = false;
for (URI currentContainer : supportedContainers){
if (mco.isContainer(currentContainer)){
rightContainer = true;
}
}
if (mco.isSufficientRuntimeEnvironment(supportedBackends)){
rightBackends = true;
}
return (rightContainer && rightBackends);
}
private static String[] retrieveProcessDescriptions(File directory){
String[] describeProcessFiles = directory.list(new FilenameFilter() {
public boolean accept(File d, String name) {
return name.endsWith(".xml");
}
});
return describeProcessFiles;
}
/**
* Checks if a given processID exists
* @param processID
* @return
*/
public boolean containsAlgorithm(String processID) {
if(registeredAlgorithms.containsKey(processID)){
return true;
}
return false;
}
/**
* Returns an IAlgorithm through GenericAGSProcessDelegator
* @param processID
* @return
*/
public IAlgorithm getAlgorithm(String processID) {
if(!containsAlgorithm(processID)){
throw new RuntimeException("Could not allocate Process " + processID);
}
try {
// create a unique directory for each instance
String randomDirName = workspaceBase + File.separator + UUID.randomUUID();
return new ArcToolboxProcessDelegator(registeredAlgorithms.get(processID), new File (randomDirName));
} catch (IOException e) {
LOGGER.error(processID + ": Instantiation failed!");
e.printStackTrace();
return null;
}
}
public Collection<String> getAlgorithmNames() {
return registeredAlgorithms.keySet();
}
public ProcessDescriptionType getProcessDescription(String processID) {
return registeredAlgorithms.get(processID).getProcessDescription();
}
@Override
public void shutdown() {
// TODO Auto-generated method stub
}
}