Gridarta Editor
Plugin.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.EvalError;
23 import bsh.Interpreter;
24 import java.io.File;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.concurrent.CopyOnWriteArrayList;
41 import nu.xom.Element;
42 import nu.xom.Node;
43 import org.apache.log4j.Category;
44 import org.apache.log4j.Logger;
45 import org.jetbrains.annotations.NotNull;
46 import org.jetbrains.annotations.Nullable;
47 
53 public class Plugin<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> implements Iterable<PluginParameter<G, A, R, ?>> {
54 
58  @NotNull
59  private static final Category LOG = Logger.getLogger(Plugin.class);
60 
64  @NotNull
65  private String code = "";
66 
70  @NotNull
71  private final List<PluginParameter<G, A, R, ?>> parameters = new ArrayList<>();
72 
76  @NotNull
77  private final String name;
78 
82  @NotNull
84 
89  @NotNull
91 
95  private boolean autoBoot;
96 
100  private boolean filter;
101 
105  private boolean script;
106 
110  @NotNull
111  private final Collection<PluginListener> listeners = new CopyOnWriteArrayList<>();
112 
117  @Nullable
118  private File file;
119 
123  private boolean modified;
124 
129  @NotNull
130  private final PluginParameterListener pluginParameterListener = this::setModified;
131 
138  public Plugin(@NotNull final String name, @NotNull final PluginParameterFactory<G, A, R> pluginParameterFactory) {
139  this.name = name;
140  this.pluginParameterFactory = pluginParameterFactory;
141  }
142 
147  @NotNull
148  public String getName() {
149  return name;
150  }
151 
156  @NotNull
157  public String getCode() {
158  return code;
159  }
160 
165  public void setCode(@NotNull final String code) {
166  if (this.code.equals(code)) {
167  return;
168  }
169 
170  this.code = code;
171  setModified();
172  }
173 
178  public boolean hasParameters() {
179  return !parameters.isEmpty();
180  }
181 
187  public int getParameter(@NotNull final String parameterName) {
188  int index = 0;
189  for (final PluginParameter<G, A, R, ?> parameter : parameters) {
190  if (parameter.getName().equals(parameterName)) {
191  return index;
192  }
193  index++;
194  }
195  return -1;
196  }
197 
198  @NotNull
199  @Override
200  public String toString() {
201  return name;
202  }
203 
207  public void newParameter() {
208  final PluginParameter<G, A, R, ?> pluginParameter;
209  try {
211  } catch (final NoSuchParameterException ex) {
212  LOG.warn("Cannot create parameter: " + ex.getMessage());
213  return;
214  }
215  parameters.add(pluginParameter);
217  setModified();
219  }
220 
225  public void removeParameter(final int index) {
226  parameters.remove(index).removePluginParameterListener(pluginParameterListener);
227  setModified();
229  }
230 
235  public void addPluginListener(@NotNull final PluginListener listener) {
236  listeners.add(listener);
237  }
238 
243  public void removePluginListener(@NotNull final PluginListener listener) {
244  listeners.remove(listener);
245  }
246 
252  for (final PluginListener listener : listeners) {
253  listener.parametersChanged();
254  }
255  }
256 
263  @NotNull
266  model.code = code;
267  model.autoBoot = autoBoot;
268  model.filter = filter;
269  model.script = script;
270  model.file = file;
271  model.modified = modified;
272  for (final PluginParameter<G, A, R, ?> parameter : parameters) {
273  final Element parameterXml = codec.toXML(parameter);
274  final PluginParameter<G, A, R, ?> clonedParam;
275  try {
276  clonedParam = pluginParameterFactory.createParameter(parameterXml);
277  } catch (final NoSuchParameterException ex) {
278  throw new AssertionError(ex);
279  }
280  model.addParameter(clonedParam);
281  }
282  return model;
283  }
284 
289  public void addParameter(@NotNull final PluginParameter<G, A, R, ?> pluginParameter) {
290  parameters.add(pluginParameter);
291  pluginParameter.addPluginParameterListener(pluginParameterListener);
292  setModified();
294  }
295 
304  try {
305  return parameters.get(index);
306  } catch (final IndexOutOfBoundsException ex) {
307  throw new NoSuchParameterException(index, ex);
308  }
309  }
310 
315  public boolean isAutoBoot() {
316  return autoBoot;
317  }
318 
323  public boolean isScript() {
324  return script;
325  }
326 
331  public boolean isFilter() {
332  return filter;
333  }
334 
339  public void setAutoBoot(final boolean autoBoot) {
340  if (this.autoBoot == autoBoot) {
341  return;
342  }
343  this.autoBoot = autoBoot;
344  setModified();
345  }
346 
351  public void setScript(final boolean script) {
352  if (this.script == script) {
353  return;
354  }
355  this.script = script;
356  setModified();
357  }
358 
363  public void setFilter(final boolean filter) {
364  if (this.filter == filter) {
365  return;
366  }
367  this.filter = filter;
368  setModified();
369  }
370 
377  public void convertType(@NotNull final PluginParameter<G, A, R, ?> pluginParameter, @NotNull final String newType) throws NoSuchParameterException {
378  final int index = parameters.indexOf(pluginParameter);
379  if (index == -1) {
380  throw new NoSuchParameterException(pluginParameter);
381  }
383  final PluginParameter<G, A, R, ?> oldParameter = parameters.set(index, newParameter);
385  newParameter.addPluginParameterListener(pluginParameterListener);
386  setModified();
388  }
389 
394  public boolean isModified() {
395  return modified;
396  }
397 
401  public void resetModified() {
402  modified = false;
403  }
404 
408  private void setModified() {
409  modified = true;
410  }
411 
417  @Nullable
418  public File getFile() {
419  return file;
420  }
421 
426  public void setFile(@Nullable final File file) {
427  this.file = file;
428  }
429 
430  @NotNull
431  @Override
432  public Iterator<PluginParameter<G, A, R, ?>> iterator() {
433  return Collections.unmodifiableList(parameters).iterator();
434  }
435 
436  public void runPlugin(@NotNull final PluginParameters pluginParameters) {
437  final Interpreter runner = new Interpreter();
438  try {
439  pluginParameters.setInterpreterValues(runner, PluginRunMode.AUTO_RUN);
440  runner.eval(code);
441  } catch (final EvalError e) {
442  LOG.warn("Evaluation error on (auto-run)" + name, e);
443  }
444  }
445 
446  @Nullable
447  public Filter<?, ?> getPluginAsFilter(@NotNull final PluginParameters pluginParameters) {
448  final Interpreter runner = new Interpreter();
449  try {
450  pluginParameters.setInterpreterValues(runner, PluginRunMode.FILTER);
451  return (Filter<?, ?>) runner.eval(code);
452  } catch (final EvalError e) {
453  LOG.warn("Evaluation error on (filter)" + name, e);
454  } catch (final ClassCastException e) {
455  LOG.warn("Plugin did not return a net.sf.gridarta.model.filter.Filter object" + name, e);
456  }
457  return null;
458  }
459 
465  @NotNull
466  public Node toXML(@NotNull final PluginParameter<G, A, R, ?> pluginParameter) {
467  return codec.toXML(pluginParameter);
468  }
469 
470 }
net.sf.gridarta.plugin
Definition: BshRunnable.java:20
net.sf.gridarta.plugin.parameter.PluginParameterCodec
Converts PluginParameters from or to XML encoding.
Definition: PluginParameterCodec.java:35
net.sf.gridarta.plugin.parameter.PluginParameter
Parameter for a Plugin.
Definition: PluginParameter.java:33
net.sf.gridarta.model.filter.Filter
Interface for Filters.
Definition: Filter.java:33
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.plugin.Plugin.setScript
void setScript(final boolean script)
Sets whether this plugin is a stand-alone plugin.
Definition: Plugin.java:351
net.sf.gridarta.plugin.Plugin.modified
boolean modified
Whether the plugin contents has been modified since last save.
Definition: Plugin.java:123
net.sf.gridarta.plugin.Plugin.getName
String getName()
Returns the name of this plugin.
Definition: Plugin.java:148
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.gridarta.plugin.Plugin.notifyParametersChangedListeners
void notifyParametersChangedListeners()
Notifies all registered PluginListeners that the parameters have changed.
Definition: Plugin.java:251
net.sf.gridarta.plugin.parameter.PluginParameterListener
Interface for listeners interested in PluginParameter related events.
Definition: PluginParameterListener.java:29
net.sf.gridarta.plugin.Plugin.hasParameters
boolean hasParameters()
Returns whether this plugin has at least one parameter.
Definition: Plugin.java:178
net.sf
net.sf.gridarta.plugin.Plugin.parameters
final List< PluginParameter< G, A, R, ?> > parameters
The PluginParameters for this plugin.
Definition: Plugin.java:71
net.sf.gridarta.plugin.parameter.PluginParameter.addPluginParameterListener
void addPluginParameterListener(@NotNull PluginParameterListener listener)
Adds a listener to be notified.
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.Plugin.toString
String toString()
Definition: Plugin.java:200
net.sf.gridarta.plugin.Plugin.Plugin
Plugin(@NotNull final String name, @NotNull final PluginParameterFactory< G, A, R > pluginParameterFactory)
Creates a new instance.
Definition: Plugin.java:138
net.sf.gridarta.plugin.Plugin.newParameter
void newParameter()
Creates a new plugin parameter.
Definition: Plugin.java:207
net.sf.gridarta.plugin.parameter.PluginParameterFactory.createParameter
PluginParameter< G, A, R, ?> createParameter(@NotNull final Element parameterNode)
Definition: PluginParameterFactory.java:73
net.sf.gridarta.plugin.parameter.StringParameter.PARAMETER_TYPE
static final String PARAMETER_TYPE
The string representation of this parameter type.
Definition: StringParameter.java:36
net.sf.gridarta.plugin.Plugin.setCode
void setCode(@NotNull final String code)
Sets the executable code of this plugin.
Definition: Plugin.java:165
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.Plugin.addPluginListener
void addPluginListener(@NotNull final PluginListener listener)
Adds a PluginListener to be notified about changes.
Definition: Plugin.java:235
net.sf.gridarta.plugin.PluginRunMode.AUTO_RUN
AUTO_RUN
Definition: PluginRunMode.java:28
net.sf.gridarta.plugin.Plugin.codec
final PluginParameterCodec< G, A, R > codec
The PluginParameterCodec for converting PluginParameters to or from XML representation.
Definition: Plugin.java:90
net.sf.gridarta.plugin.Plugin.toXML
Node toXML(@NotNull final PluginParameter< G, A, R, ?> pluginParameter)
Returns XML representation for a PluginParameter.
Definition: Plugin.java:466
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.Plugin.addParameter
void addParameter(@NotNull final PluginParameter< G, A, R, ?> pluginParameter)
Adds a plugin parameter to this plugin.
Definition: Plugin.java:289
net.sf.gridarta.plugin.Plugin.file
File file
The location to save this plugin to; set to.
Definition: Plugin.java:118
net.sf.gridarta.plugin.Plugin.setModified
void setModified()
Marks this plugin a modified since last save.
Definition: Plugin.java:408
net.sf.gridarta.plugin.Plugin.runPlugin
void runPlugin(@NotNull final PluginParameters pluginParameters)
Definition: Plugin.java:436
net.sf.gridarta.plugin.PluginListener
Interface for listeners interested in Plugin related events.
Definition: PluginListener.java:28
net.sf.gridarta.plugin.Plugin.name
final String name
The plugin name.
Definition: Plugin.java:77
net.sf.gridarta.plugin.Plugin.filter
boolean filter
Whether this plugin is a filter.
Definition: Plugin.java:100
net.sf.gridarta.plugin.Plugin.code
String code
The executable code.
Definition: Plugin.java:65
net.sf.gridarta.model.maparchobject.MapArchObject
Interface for MapArchObjects.
Definition: MapArchObject.java:40
net.sf.gridarta.plugin.Plugin.isScript
boolean isScript()
Returns whether this plugin is a stand-alone plugin.
Definition: Plugin.java:323
net.sf.gridarta.plugin.Plugin.setAutoBoot
void setAutoBoot(final boolean autoBoot)
Sets whether this plugin is run whenever the editor starts.
Definition: Plugin.java:339
net.sf.gridarta.model.filter
Definition: AbstractFilterConfig.java:20
net.sf.gridarta.plugin.Plugin.LOG
static final Category LOG
The Logger for printing log messages.
Definition: Plugin.java:59
net.sf.gridarta.plugin.Plugin.getPluginAsFilter
Filter<?, ?> getPluginAsFilter(@NotNull final PluginParameters pluginParameters)
Definition: Plugin.java:447
net.sf.gridarta.plugin.Plugin.isFilter
boolean isFilter()
Returns whether this plugin is a filter.
Definition: Plugin.java:331
net.sf.gridarta.plugin.Plugin.convertType
void convertType(@NotNull final PluginParameter< G, A, R, ?> pluginParameter, @NotNull final String newType)
Changes the type of a plugin parameter.
Definition: Plugin.java:377
net.sf.gridarta.plugin.Plugin.autoBoot
boolean autoBoot
Whether this plugin is run whenever the editor starts.
Definition: Plugin.java:95
net.sf.gridarta.plugin.Plugin.removePluginListener
void removePluginListener(@NotNull final PluginListener listener)
Removes a PluginListener to be notified about changes.
Definition: Plugin.java:243
net.sf.gridarta.plugin.Plugin.setFilter
void setFilter(final boolean filter)
Sets whether this plugin is a filter.
Definition: Plugin.java:363
net.sf.gridarta.plugin.Plugin.removeParameter
void removeParameter(final int index)
Removes a plugin parameter.
Definition: Plugin.java:225
net.sf.gridarta.plugin.PluginRunMode
The run mode of a plugin plugin.
Definition: PluginRunMode.java:26
net.sf.gridarta.plugin.Plugin.setFile
void setFile(@Nullable final File file)
Sets the location to save this plugin to.
Definition: Plugin.java:426
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Reflects an Archetype.
Definition: Archetype.java:41
net.sf.gridarta.plugin.Plugin
Model for plugins.
Definition: Plugin.java:53
net.sf.gridarta.plugin.Plugin.pluginParameterListener
final PluginParameterListener pluginParameterListener
The PluginParameterListener that is attached to all {plugin parameters} to detect changes.
Definition: Plugin.java:130
net.sf.gridarta.plugin.Plugin.iterator
Iterator< PluginParameter< G, A, R, ?> > iterator()
Definition: Plugin.java:432
net.sf.gridarta.plugin.parameter.PluginParameterCodec.toXML
final PluginParameterVisitor< G, A, R, Element > toXML
A PluginParameterVisitor that returns XML representation.
Definition: PluginParameterCodec.java:41
net.sf.gridarta.plugin.PluginRunMode.FILTER
FILTER
Definition: PluginRunMode.java:32
net.sf.gridarta.plugin.parameter.PluginParameterFactory
Factory for Plugin Parameters.
Definition: PluginParameterFactory.java:37
net.sf.gridarta.plugin.Plugin.isAutoBoot
boolean isAutoBoot()
Returns whether this plugin is run whenever the editor starts.
Definition: Plugin.java:315
net.sf.gridarta.plugin.Plugin.listeners
final Collection< PluginListener > listeners
The PluginListeners to inform about changes.
Definition: Plugin.java:111
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.plugin.Plugin.pluginParameterFactory
final PluginParameterFactory< G, A, R > pluginParameterFactory
The PluginParameterFactory for creating plugin parameters.
Definition: Plugin.java:83
net.sf.gridarta.plugin.Plugin.getFile
File getFile()
Returns the location to save this plugin to.
Definition: Plugin.java:418
net.sf.gridarta.plugin.parameter.PluginParameter.removePluginParameterListener
void removePluginParameterListener(@NotNull PluginParameterListener listener)
Removes a listener to be notified.
net.sf.gridarta.plugin.parameter.StringParameter
A PluginParameter that holds a string value.
Definition: StringParameter.java:30
net.sf.gridarta.plugin.Plugin.resetModified
void resetModified()
Marks the plugin as unmodified since last save.
Definition: Plugin.java:401
net.sf.gridarta.plugin.Plugin.getParameter
PluginParameter< G, A, R, ?> getParameter(final int index)
Returns the PluginParameter at a given index.
Definition: Plugin.java:303
net.sf.gridarta.plugin.Plugin.script
boolean script
Whether this plugin is a stand-alone plugin.
Definition: Plugin.java:105
net.sf.gridarta.plugin.Plugin.getCode
String getCode()
Returns the executable code of this plugin.
Definition: Plugin.java:157
net.sf.gridarta.plugin.Plugin.isModified
boolean isModified()
Returns whether the plugin contents have been modified since last save.
Definition: Plugin.java:394
net.sf.gridarta.plugin.parameter
Definition: AbstractPathParameter.java:20