Gridarta Editor
PluginExecutor.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2023 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.plugin;
21 
22 import bsh.ConsoleInterface;
23 import bsh.EvalError;
24 import bsh.Interpreter;
25 import bsh.TargetError;
26 import java.io.CharArrayWriter;
27 import java.io.InputStreamReader;
28 import java.io.PrintStream;
29 import java.io.PrintWriter;
30 import java.io.Reader;
31 import java.util.HashMap;
32 import java.util.Map;
33 import java.util.Map.Entry;
40 import org.jetbrains.annotations.NotNull;
41 import org.jetbrains.annotations.Nullable;
42 
47 @SuppressWarnings("UseOfSystemOutOrSystemErr")
48 public class PluginExecutor<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
49 
53  @NotNull
55 
59  @NotNull
61 
67  public PluginExecutor(@NotNull final PluginModel<G, A, R> pluginModel, @NotNull final PluginParameters pluginParameters) {
68  this.pluginModel = pluginModel;
69  this.pluginParameters = pluginParameters;
70  }
71 
78  public int executePlugin(@NotNull final String plugin, @NotNull final Iterable<String> parameters) {
79  final Plugin<G, A, R> modelTemplate = pluginModel.getPlugin(plugin);
80  if (modelTemplate == null) {
81  System.err.println("plugin " + plugin + " does not exist");
82  return 1;
83  }
84 
85  final Plugin<G, A, R> clonedPlugin = modelTemplate.clonePlugin();
86  final Map<String, Object> runValues = new HashMap<>();
87  for (final String parameter : parameters) {
88  final String[] tmp = StringUtils.PATTERN_EQUAL.split(parameter, 2);
89  if (tmp.length != 2) {
90  System.err.println("syntax error: " + parameter);
91  return 1;
92  }
93 
94  final int index = clonedPlugin.getParameter(tmp[0]);
95  if (index == -1) {
96  final StringBuilder sb = new StringBuilder();
97  boolean firstParameter = true;
98  for (final PluginParameter<?, ?, ?, ?> clonedParameter : clonedPlugin) {
99  sb.append(firstParameter ? " " : ", ");
100  sb.append(clonedParameter.getName());
101  firstParameter = false;
102  }
103  System.err.println("plugin " + plugin + " has no parameter " + tmp[0] + "; available parameters:" + sb);
104  return 1;
105  }
106 
107  final PluginParameter<G, A, R, ?> clonedParameter;
108  try {
109  clonedParameter = clonedPlugin.getParameter(index);
110  } catch (final NoSuchParameterException ex) {
111  throw new AssertionError(ex);
112  }
113  if (!clonedParameter.setStringValue(tmp[1])) {
114  System.out.println("invalid value " + tmp[1] + " for parameter " + tmp[0]);
115  return 1;
116  }
117 
118  runValues.put(clonedParameter.getName(), tmp[1]);
119  }
120  for (final PluginParameter<G, A, R, ?> parameter : clonedPlugin) {
121  final String parameterName = parameter.getName();
122  if (!runValues.containsKey(parameterName)) {
123  final Object parameterValue = parameter.getValueOrNull();
124  if (parameterValue == null) {
125  System.err.println("no value for parameter " + parameterName);
126  return 1;
127  }
128  runValues.put(parameterName, parameterValue);
129  }
130  }
131 
132  final ConsoleInterface console = new ConsoleInterface() {
133 
134  @Override
135  public Reader getIn() {
136  return new InputStreamReader(System.in);
137  }
138 
139  @Override
140  public PrintStream getOut() {
141  return System.out;
142  }
143 
144  @Override
145  public PrintStream getErr() {
146  return System.err;
147  }
148 
149  @Override
150  public void println(final Object o) {
151  System.out.println(o);
152  }
153 
154  @Override
155  public void print(final Object o) {
156  System.out.print(o);
157  }
158 
159  @Override
160  public void error(final Object o) {
161  System.err.println(o);
162  }
163 
164  };
165  final BshRunnable<G, A, R> pluginRunnable = doRunPlugin(clonedPlugin, console, runValues);
166  if (pluginRunnable == null) {
167  return 1;
168  }
169  final Thread pluginThread = new Thread(pluginRunnable, clonedPlugin.getName());
170  pluginThread.start();
171  try {
172  pluginThread.join();
173  } catch (final InterruptedException ignored) {
174  pluginThread.interrupt();
175  Thread.currentThread().interrupt();
176  System.out.println("interrupted");
177  return 1;
178  }
179 
180  if (!pluginRunnable.isSuccess()) {
181  System.err.println("plugin failed");
182  return 1;
183  }
184 
185  return 0;
186  }
187 
195  @Nullable
196  public BshRunnable<G, A, R> doRunPlugin(@NotNull final Plugin<G, A, R> plugin, @NotNull final ConsoleInterface console, @NotNull final Map<String, Object> parameters) {
197  final Interpreter runner = new Interpreter();
198  runner.setConsole(console);
199  try {
200  pluginParameters.setInterpreterValues(runner, PluginRunMode.BATCH);
201  for (final Entry<String, Object> parameter : parameters.entrySet()) {
202  runner.set(parameter.getKey(), parameter.getValue());
203  }
204  } catch (final TargetError ex) {
205  final CharArrayWriter charArrayWriter = new CharArrayWriter();
206  try {
207  try (PrintWriter printWriter = new PrintWriter(charArrayWriter)) {
208  ex.getTarget().printStackTrace(printWriter);
209  }
210  } finally {
211  charArrayWriter.close();
212  }
213  console.print("target error: " + charArrayWriter);
214  return null;
215  } catch (final EvalError ex) {
216  console.print("evaluation error: " + ex.getMessage());
217  return null;
218  }
219  return new BshRunnable<>(plugin, runner);
220  }
221 
222 }
net.sf.gridarta.plugin
Definition: BshRunnable.java:20
net.sf.gridarta.plugin.parameter.PluginParameter
Parameter for a Plugin.
Definition: PluginParameter.java:33
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.plugin.PluginExecutor.doRunPlugin
BshRunnable< G, A, R > doRunPlugin(@NotNull final Plugin< G, A, R > plugin, @NotNull final ConsoleInterface console, @NotNull final Map< String, Object > parameters)
Runs a plugin model.
Definition: PluginExecutor.java:196
net.sf.gridarta.plugin.PluginExecutor.pluginParameters
final PluginParameters pluginParameters
The parameters to pass to the plugin.
Definition: PluginExecutor.java:60
net.sf.gridarta.plugin.Plugin.getParameter
int getParameter(@NotNull final String parameterName)
Returns the index for a plugin parameter name.
Definition: Plugin.java:187
net.sf
net.sf.gridarta.plugin.Plugin.clonePlugin
Plugin< G, A, R > clonePlugin()
Returns a clone copy of this plugin.
Definition: Plugin.java:264
net.sf.gridarta.plugin.PluginExecutor.pluginModel
final PluginModel< G, A, R > pluginModel
The PluginModel to execute.
Definition: PluginExecutor.java:54
net.sf.gridarta.plugin.PluginExecutor
Allows execution of Plugins.
Definition: PluginExecutor.java:48
net.sf.gridarta.model.archetype
Definition: AbstractArchetype.java:20
net.sf.gridarta.model.gameobject.GameObject
Reflects a game object (object on a map).
Definition: GameObject.java:36
net.sf.gridarta.plugin.PluginParameters
Makes basic Gridarta classes available to scripts.
Definition: PluginParameters.java:34
net.sf.gridarta.plugin.BshRunnable
A BshThread.
Definition: BshRunnable.java:34
net.sf.gridarta.plugin.PluginExecutor.executePlugin
int executePlugin(@NotNull final String plugin, @NotNull final Iterable< String > parameters)
Executes an editor plugin.
Definition: PluginExecutor.java:78
net.sf.gridarta.plugin.parameter.NoSuchParameterException
Thrown if a parameter does not exist.
Definition: NoSuchParameterException.java:29
net.sf.gridarta.model.gameobject
GameObjects are the objects based on Archetypes found on maps.
Definition: AbstractGameObject.java:20
net
net.sf.gridarta.plugin.PluginParameters.setInterpreterValues
void setInterpreterValues(@NotNull final Interpreter interpreter, @NotNull final PluginRunMode pluginRunMode)
Adds variables to a Interpreter instance.
Definition: PluginParameters.java:57
net.sf.gridarta.model.maparchobject.MapArchObject
Interface for MapArchObjects.
Definition: MapArchObject.java:40
net.sf.gridarta.plugin.PluginModel.getPlugin
Plugin< G, A, R > getPlugin(@NotNull final String name)
Definition: PluginModel.java:79
net.sf.gridarta.plugin.parameter.PluginParameter.setStringValue
boolean setStringValue(@NotNull String stringValue)
Sets the parameter value from string representation.
net.sf.gridarta.plugin.parameter.PluginParameter.getName
String getName()
The name of the parameter.
net.sf.gridarta.utils.StringUtils
Utility class for string manipulation.
Definition: StringUtils.java:31
net.sf.gridarta.plugin.PluginRunMode
The run mode of a plugin plugin.
Definition: PluginRunMode.java:26
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Reflects an Archetype.
Definition: Archetype.java:41
net.sf.gridarta.plugin.Plugin< G, A, R >
net.sf.gridarta.plugin.PluginExecutor.PluginExecutor
PluginExecutor(@NotNull final PluginModel< G, A, R > pluginModel, @NotNull final PluginParameters pluginParameters)
Creates a new instance.
Definition: PluginExecutor.java:67
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.plugin.PluginRunMode.BATCH
BATCH
Definition: PluginRunMode.java:30
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.plugin.parameter
Definition: AbstractPathParameter.java:20
net.sf.gridarta.plugin.BshRunnable.isSuccess
boolean isSuccess()
Returns whether the plugin has been executed successfully.
Definition: BshRunnable.java:78
net.sf.gridarta.plugin.PluginModel< G, A, R >
net.sf.gridarta.utils.StringUtils.PATTERN_EQUAL
static final Pattern PATTERN_EQUAL
The pattern that matches a single equal sign ("=").
Definition: StringUtils.java:103