/** * 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.grass; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import net.opengis.wps.x100.ProcessDescriptionType; import org.n52.wps.PropertyDocument.Property; import org.n52.wps.commons.WPSConfig; import org.n52.wps.server.IAlgorithm; import org.n52.wps.server.IAlgorithmRepository; import org.n52.wps.server.grass.util.GRASSWPSConfigVariables; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Benjamin Pross (bpross-52n) * */ public class GrassProcessRepository implements IAlgorithmRepository { private static Logger LOGGER = LoggerFactory.getLogger(GrassProcessRepository.class); private Map<String, ProcessDescriptionType> registeredProcesses; private Map<String, Boolean> processesAddonFlagMap; private final String fileSeparator = System.getProperty("file.separator"); public static String tmpDir; public static String grassHome; public static String pythonHome; public static String pythonPath; public static String grassModuleStarterHome; public static String gisrcDir; public static String addonPath; public GrassProcessRepository() { registeredProcesses = new HashMap<String, ProcessDescriptionType>(); processesAddonFlagMap = new HashMap<String, Boolean>(); // check if the repository is active if (WPSConfig.getInstance().isRepositoryActive( this.getClass().getCanonicalName())) { LOGGER.info("Initializing Grass Repository"); Property[] propertyArray = WPSConfig.getInstance() .getPropertiesForRepositoryClass( this.getClass().getCanonicalName()); /* * get properties of Repository * * check whether process is amongst them and active * * if properties are empty (not initialized yet) * add all valid processes to WPSConfig */ ArrayList<String> processList = new ArrayList<String>(propertyArray.length); for (Property property : propertyArray) { if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.TMP_Dir.toString())) { tmpDir = property.getStringValue(); } if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.Grass_Home.toString())) { grassHome = property.getStringValue(); } else if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.ModuleStarter_Home.toString())) { grassModuleStarterHome = property.getStringValue(); } else if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.Python_Home.toString())) { pythonHome = property.getStringValue(); } else if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.GISRC_Dir.toString())) { gisrcDir = property.getStringValue(); }else if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.Addon_Dir.toString())) { addonPath = property.getStringValue(); }else if (property.getName().equalsIgnoreCase( GRASSWPSConfigVariables.Python_Path.toString())) { pythonPath = property.getStringValue(); }else if(property.getName().equals("Algorithm")){ if(property.getActive()){ processList.add(property.getStringValue()); }else{ LOGGER.info("GRASS process : " + property.getStringValue() + " not active."); } } } HashMap<String, String> variableMap = new HashMap<String, String>(); variableMap.put(GRASSWPSConfigVariables.TMP_Dir.toString(), tmpDir); variableMap.put(GRASSWPSConfigVariables.Grass_Home.toString(), grassHome); variableMap.put( GRASSWPSConfigVariables.ModuleStarter_Home.toString(), grassModuleStarterHome); variableMap.put(GRASSWPSConfigVariables.Python_Home.toString(), pythonHome); variableMap.put(GRASSWPSConfigVariables.GISRC_Dir.toString(), gisrcDir); variableMap.put(GRASSWPSConfigVariables.Python_Path.toString(), pythonPath); for (String variable : variableMap.keySet()) { if (variableMap.get(variable) == null) { throw new RuntimeException("Variable " + variable + " not initialized."); } } File tmpDirectory = new File(tmpDir); if (tmpDirectory.exists()) { File[] filesToDelete = tmpDirectory.listFiles(); for (File file : filesToDelete) { try { if (file.isDirectory()) { deleteFiles(file); } else { file.delete(); } } catch (Exception e) { /* * ignore */ } } } // initialize after properties are fetched GrassProcessDescriptionCreator creator = new GrassProcessDescriptionCreator(); File processDirectory = new File(grassHome + fileSeparator + "bin"); if (processDirectory.isDirectory()) { String[] processes = processDirectory.list(); for (String process : processes) { if (process.endsWith(".exe")) { process = process.replace(".exe", ""); } if (processList.contains(process)) { ProcessDescriptionType pDescType; try { pDescType = creator .createDescribeProcessType(process, false); if (pDescType != null) { registeredProcesses.put(process, pDescType); processesAddonFlagMap.put(process, false); LOGGER.info("GRASS process " + process + " added."); } } catch (Exception e) { LOGGER.warn("Could not add Grass process : " + process + ". Errors while creating process description"); LOGGER.error(e.getMessage(), e); } } else { LOGGER.info("Did not add GRASS process : " + process +". Not in Repository properties or not active."); } } } if(addonPath != null){ File addonDirectory = new File(addonPath); if (addonDirectory.isDirectory()) { String[] processes = addonDirectory.list(); for (String process : processes) { if (process.endsWith(".py")) { process = process.replace(".py", ""); } if (process.endsWith(".bat")) { process = process.replace(".bat", ""); } if (process.endsWith(".exe")) { process = process.replace(".exe", ""); } if (processList.contains(process)) { ProcessDescriptionType pDescType; try { if(registeredProcesses.keySet().contains(process)){ LOGGER.info("Skipping duplicate process " + process); continue; } pDescType = creator .createDescribeProcessType(process, true); if (pDescType != null) { registeredProcesses.put(process, pDescType); processesAddonFlagMap.put(process, true); LOGGER.info("GRASS Addon process " + process + " added."); } } catch (Exception e) { LOGGER.warn("Could not add Grass Addon process : " + process + ". Errors while creating process description"); LOGGER.error(e.getMessage(), e); } } else { LOGGER.info("Did not add GRASS Addon process : " + process +". Not in Repository properties or not active."); } } } } } else { LOGGER.debug("GRASS Algorithm Repository is inactive."); } } public boolean containsAlgorithm(String processID) { if (registeredProcesses.containsKey(processID)) { return true; } LOGGER.warn("Could not find Grass process " + processID); return false; } public IAlgorithm getAlgorithm(String processID) { if (!containsAlgorithm(processID)) { throw new RuntimeException("Could not allocate process"); } return new GrassProcessDelegator(processID, registeredProcesses.get(processID), processesAddonFlagMap.get(processID)); } public Collection<String> getAlgorithmNames() { return registeredProcesses.keySet(); } private void deleteFiles(File tmpDirectory) { File[] filesToDelete = tmpDirectory.listFiles(); for (File file : filesToDelete) { try { if (file.isDirectory()) { deleteFiles(file); } else { file.delete(); } } catch (Exception e) { /* * ignore */ } } tmpDirectory.delete(); } @Override public ProcessDescriptionType getProcessDescription(String processID) { if(!registeredProcesses.containsKey(processID)){ registeredProcesses.put(processID, getAlgorithm(processID).getDescription()); } return registeredProcesses.get(processID); } @Override public void shutdown() { // TODO Auto-generated method stub } }