/*
* Copyright (C) 2012 Dr. John Lindsay <jlindsay@uoguelph.ca>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package whitebox.plugins;
import java.awt.Font;
import java.io.BufferedReader;
import whitebox.interfaces.WhiteboxPluginHost;
import whitebox.interfaces.WhiteboxPlugin;
import whitebox.ui.plugin_dialog.ToolDialog;
import java.util.ArrayList;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import whitebox.interfaces.MapLayer;
import whitebox.utilities.FileUtilities;
/**
* Serves as a basic PluginHost used for running plugin tools outside of the Whitebox GAT user interface.
* @author Dr. John Lindsay email: jlindsay@uoguelph.ca
*/
public class PluginHost implements WhiteboxPluginHost {
private ArrayList<PluginInfo> plugInfo = null;
private static PluginService pluginService = null;
private String pathSep;
public String pluginsDirectory = null;
private String helpDirectory = null;
private String applicationDirectory = null;
private String resourcesDirectory = null;
private String workingDirectory = null;
public PluginHost() {
loadPlugins();
}
private boolean loadPlugins() {
try {
pathSep = File.separator;
applicationDirectory = java.net.URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8");
//getClass().getProtectionDomain().
if (applicationDirectory.endsWith(".exe") || applicationDirectory.endsWith(".jar")) {
applicationDirectory = new File(applicationDirectory).getParent();
} else {
// Add the path to the class files
applicationDirectory += getClass().getName().replace('.', File.separatorChar);
// Step one level up as we are only interested in the
// directory containing the class files
applicationDirectory = new File(applicationDirectory).getParent();
}
resourcesDirectory = applicationDirectory + pathSep + "resources" + pathSep;
findFile(new File(new File(new File(applicationDirectory).getParent()).getParent()), "toolbox.xml");
if (retFile != null && !retFile.isEmpty()) {
resourcesDirectory = new File(retFile).getParent() + pathSep;
}
workingDirectory = resourcesDirectory + "samples" + pathSep;
String seedDirectory = applicationDirectory;
findPluginsDirectory(new File(seedDirectory));
if (pluginsDirectory == null) {
do {
int i = seedDirectory.lastIndexOf(pathSep);
seedDirectory = seedDirectory.substring(0, i);
findPluginsDirectory(new File(seedDirectory));
} while (pluginsDirectory == null && seedDirectory.length() > 0);
}
seedDirectory = applicationDirectory;
findHelpDirectory(new File(seedDirectory));
if (helpDirectory == null) {
do {
int i = seedDirectory.lastIndexOf(pathSep);
seedDirectory = seedDirectory.substring(0, i);
findHelpDirectory(new File(seedDirectory));
} while (helpDirectory == null && seedDirectory.length() > 0);
}
pluginService = PluginServiceFactory.createPluginService(applicationDirectory);
pluginService.initPlugins();
plugInfo = pluginService.getPluginList();
loadScripts();
return true;
} catch (Exception e) {
return false;
}
}
private void loadScripts() {
ArrayList<String> pythonScripts = FileUtilities.findAllFilesWithExtension(resourcesDirectory, ".py", true);
ArrayList<String> groovyScripts = FileUtilities.findAllFilesWithExtension(resourcesDirectory, ".groovy", true);
ArrayList<String> jsScripts = FileUtilities.findAllFilesWithExtension(resourcesDirectory, ".js", true);
//ArrayList<PluginInfo> scriptPlugins = new ArrayList<>();
for (String str : pythonScripts) {
try {
// Open the file
FileInputStream fstream = new FileInputStream(str);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
boolean containsName = false;
boolean containsDescriptiveName = false;
boolean containsDescription = false;
boolean containsToolboxes = false;
String name = "";
String descriptiveName = "";
String description = "";
String[] toolboxes = null;
while ((strLine = br.readLine()) != null
&& (!containsName || !containsDescriptiveName
|| !containsDescription || !containsToolboxes)) {
if (strLine.startsWith("name = \"")) {
containsName = true;
// now retreive the name
String[] str2 = strLine.split("=");
name = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.startsWith("descriptiveName = \"")) {
containsDescriptiveName = true;
String[] str2 = strLine.split("=");
descriptiveName = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.startsWith("description = \"")) {
containsDescription = true;
String[] str2 = strLine.split("=");
description = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.startsWith("toolboxes = [\"")) {
containsToolboxes = true;
String[] str2 = strLine.split("=");
toolboxes = str2[str2.length - 1].replace("\"", "").replace("\'", "").replace("[", "").replace("]", "").trim().split(",");
for (int i = 0; i < toolboxes.length; i++) {
toolboxes[i] = toolboxes[i].trim();
}
}
}
//Close the input stream
br.close();
if (containsName && containsDescriptiveName
&& containsDescription && containsToolboxes) {
// it's a plugin!
PluginInfo pi = new PluginInfo(name, descriptiveName,
description, toolboxes, PluginInfo.SORT_MODE_NAMES);
pi.setScript(true);
pi.setScriptFile(str);
plugInfo.add(pi);
//scriptPlugins.add(pi);
}
} catch (IOException ioe) {
System.out.println(ioe.getStackTrace());
}
}
for (String str : jsScripts) {
try {
// Open the file
FileInputStream fstream = new FileInputStream(str);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
boolean containsName = false;
boolean containsDescriptiveName = false;
boolean containsDescription = false;
boolean containsToolboxes = false;
String name = "";
String descriptiveName = "";
String description = "";
String[] toolboxes = null;
while ((strLine = br.readLine()) != null
&& (!containsName || !containsDescriptiveName
|| !containsDescription || !containsToolboxes)) {
if (strLine.toLowerCase().contains("name = \"")
&& !strLine.toLowerCase().contains("descriptivename")) {
containsName = true;
// now retreive the name
String[] str2 = strLine.split("=");
name = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("descriptivename = \"")) {
containsDescriptiveName = true;
String[] str2 = strLine.split("=");
descriptiveName = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("description = \"")) {
containsDescription = true;
String[] str2 = strLine.split("=");
description = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("toolboxes = [\"")) {
containsToolboxes = true;
String[] str2 = strLine.split("=");
toolboxes = str2[str2.length - 1].replace("\"", "").replace("\'", "").replace("[", "").replace("]", "").trim().split(",");
for (int i = 0; i < toolboxes.length; i++) {
toolboxes[i] = toolboxes[i].trim();
}
}
}
//Close the input stream
br.close();
if (containsName && containsDescriptiveName
&& containsDescription && containsToolboxes) {
// it's a plugin!
PluginInfo pi = new PluginInfo(name, descriptiveName,
description, toolboxes, PluginInfo.SORT_MODE_NAMES);
pi.setScript(true);
pi.setScriptFile(str);
plugInfo.add(pi);
//scriptPlugins.add(pi);
}
} catch (IOException ioe) {
System.out.println(ioe.getStackTrace());
}
}
for (String str : groovyScripts) {
try {
// Open the file
FileInputStream fstream = new FileInputStream(str);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
boolean containsName = false;
boolean containsDescriptiveName = false;
boolean containsDescription = false;
boolean containsToolboxes = false;
String name = "";
String descriptiveName = "";
String description = "";
String[] toolboxes = null;
while ((strLine = br.readLine()) != null
&& (!containsName || !containsDescriptiveName
|| !containsDescription || !containsToolboxes)) {
if (strLine.toLowerCase().contains("name = \"")
&& !strLine.toLowerCase().contains("descriptivename")) {
containsName = true;
// now retreive the name
String[] str2 = strLine.split("=");
name = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("descriptivename = \"")) {
containsDescriptiveName = true;
String[] str2 = strLine.split("=");
descriptiveName = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("description = \"")) {
containsDescription = true;
String[] str2 = strLine.split("=");
description = str2[str2.length - 1].replace("\"", "").replace("\'", "").trim();
} else if (strLine.toLowerCase().contains("toolboxes = [\"")) {
containsToolboxes = true;
String[] str2 = strLine.split("=");
toolboxes = str2[str2.length - 1].replace("\"", "").replace("\'", "").replace("[", "").replace("]", "").trim().split(",");
for (int i = 0; i < toolboxes.length; i++) {
toolboxes[i] = toolboxes[i].trim();
}
}
}
//Close the input stream
br.close();
if (containsName && containsDescriptiveName
&& containsDescription && containsToolboxes) {
// it's a plugin!
PluginInfo pi = new PluginInfo(name, descriptiveName,
description, toolboxes, PluginInfo.SORT_MODE_NAMES);
pi.setScript(true);
pi.setScriptFile(str);
plugInfo.add(pi);
//scriptPlugins.add(pi);
}
} catch (IOException ioe) {
System.out.println(ioe.getStackTrace());
}
}
}
@Override
public List returnPluginList() {
List<String> ret = new ArrayList<>();
for (int i = 0; i < plugInfo.size(); i++) {
ret.add(plugInfo.get(i).getName());
}
Collections.sort(ret);
return ret;
}
public int getNumberOfPlugins() {
return plugInfo.size();
}
private void findPluginsDirectory(File dir) {
File[] files = dir.listFiles();
for (int x = 0; x < files.length; x++) {
if (files[x].isDirectory()) {
if (files[x].toString().endsWith(pathSep + "resources" + pathSep + "plugins")) {
pluginsDirectory = files[x].toString() + pathSep;
break;
} else {
findPluginsDirectory(files[x]);
}
}
}
}
private void findHelpDirectory(File dir) {
File[] files = dir.listFiles();
for (int x = 0; x < files.length; x++) {
if (files[x].isDirectory()) {
if (files[x].toString().endsWith(pathSep + "resources" + pathSep + "Help")) {
helpDirectory = files[x].toString() + pathSep;
break;
} else {
findHelpDirectory(files[x]);
}
}
}
}
@Override
public void cancelOperation() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void launchDialog(String pluginName) {
WhiteboxPlugin plug = pluginService.getPlugin(pluginName, StandardPluginService.DESCRIPTIVE_NAME);
String helpFile = helpDirectory + plug.getName() + ".html";
ToolDialog dlg = new ToolDialog(this, true, plug.getName(), plug.getDescriptiveName(), helpFile);
dlg.setSize(800, 400);
dlg.setVisible(true);
dlg.dispose();
}
@Override
public void returnData(Object ret) {
}
@Override
public void runPlugin(String pluginName, String[] args, boolean runOnDedicatedThread) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void runPlugin(String pluginName, String[] args) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void pluginComplete() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int showFeedback(String message) {
System.err.println(message);
return 0;
}
@Override
public int showFeedback(String message, int optionType, int messageType) {
System.err.println(message);
return 0;
}
@Override
public void updateProgress(String progressLabel, int progress) {
System.out.println(progressLabel + " " + progress + "%");
}
@Override
public void updateProgress(int progress) {
System.out.println(progress + "%");
}
@Override
public void refreshMap(boolean updateLayersTab) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String getWorkingDirectory() {
return workingDirectory;
}
@Override
public void setWorkingDirectory(String workingDirectory) {
this.workingDirectory = workingDirectory;
}
@Override
public String getApplicationDirectory() {
return applicationDirectory;
}
@Override
public void setApplicationDirectory(String applicationDirectory) {
this.applicationDirectory = applicationDirectory;
}
@Override
public String getResourcesDirectory() {
return resourcesDirectory;
}
@Override
public String getHelpDirectory() {
return helpDirectory;
}
@Override
public void editVector() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void deleteFeature() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
Font defaultFont = new Font("SanSerif", Font.PLAIN, 10);
@Override
public Font getDefaultFont() {
return defaultFont;
}
@Override
public String getLogDirectory() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public ResourceBundle getGuiLabelsBundle() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public ResourceBundle getMessageBundle() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getLanguageCountryCode() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setLanguageCountryCode(String code) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void logException(String message, Exception e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void logThrowable(String message, Throwable t) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void logMessage(Level level, String message) {
throw new UnsupportedOperationException("Not supported yet.");
}
private String retFile;
private boolean flag = true;
private void findFile(File dir, String fileName) {
if (flag) {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
if (files[i].getName().equals(fileName)) {
retFile = files[i].toString();
flag = false;
break;
} else {
findFile(files[i], fileName);
}
} else if (files[i].getName().equals(fileName)) {
retFile = files[i].toString();
flag = false;
break;
}
}
}
}
@Override
public boolean isRequestForOperationCancelSet() {
return false;
}
@Override
public void resetRequestForOperationCancel() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void runPlugin(String pluginName, String[] args, boolean runOnDedicatedThread, boolean suppressReturnedData) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String[] getCurrentlyDisplayedFiles() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void showHelp() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void showHelp(String helpFile) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void deleteLastNodeInFeature() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setSelectFeature() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void deselectAllFeaturesInActiveLayer() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void saveSelection() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public MapLayer getActiveMapLayer() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setActiveMapLayer(int layerNumber) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public ArrayList<MapLayer> getAllMapLayers() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomToFullExtent() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomIn() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomOut() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomToLayer() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomToPage() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void zoomToSelection() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}