Search in sources :

Example 1 with Event

use of com.laytonsmith.core.events.Event in project CommandHelper by EngineHub.

the class ExtensionTracker method registerEvent.

public void registerEvent(Event e) {
    if (e instanceof AbstractEvent) {
        AbstractEvent ae = (AbstractEvent) e;
        // Get the mixin for this server, and add it to e
        Class mixinClass = StaticLayer.GetServerEventMixin();
        try {
            Constructor mixinConstructor = mixinClass.getConstructor(AbstractEvent.class);
            EventMixinInterface mixin = (EventMixinInterface) mixinConstructor.newInstance(e);
            ae.setAbstractEventMixin(mixin);
        } catch (Exception ex) {
            // This is a serious problem, and it should kill the plugin, for fast failure detection.
            throw new Error("Could not properly instantiate the mixin class. " + "The constructor with the signature \"public " + mixinClass.getSimpleName() + "(AbstractEvent e)\" is missing" + " from " + mixinClass.getName());
        }
    }
    // Finally, add it to the list, and hook it.
    if (!events.containsKey(e.driver())) {
        events.put(e.driver(), new TreeSet<Event>());
    }
    events.get(e.driver()).add(e);
}
Also used : Constructor(java.lang.reflect.Constructor) EventMixinInterface(com.laytonsmith.core.events.EventMixinInterface) Event(com.laytonsmith.core.events.Event) AbstractEvent(com.laytonsmith.core.events.AbstractEvent) AbstractEvent(com.laytonsmith.core.events.AbstractEvent)

Example 2 with Event

use of com.laytonsmith.core.events.Event in project CommandHelper by EngineHub.

the class ExtensionDocGen method generate.

public static void generate(File inputExtension, OutputStream outputStream) throws InstantiationException, IllegalAccessException, MalformedURLException, IOException {
    ClassDiscovery customDiscovery = new ClassDiscovery();
    ClassDiscoveryCache cache = new ClassDiscoveryCache(CommandHelperFileLocations.getDefault().getCacheDirectory());
    customDiscovery.setClassDiscoveryCache(cache);
    URL url = new URL("jar:" + inputExtension.toURI().toURL() + "!/");
    customDiscovery.addDiscoveryLocation(url);
    customDiscovery.setDefaultClassLoader(ExtensionDocGen.class.getClassLoader());
    StringBuilder fdocs = new StringBuilder();
    DynamicClassLoader classloader = new DynamicClassLoader();
    classloader.addJar(url);
    // functions
    HashMap<Class<?>, ArrayList<Class<? extends Function>>> functionMap = new HashMap<>();
    for (Class<? extends Function> cf : customDiscovery.loadClassesWithAnnotationThatExtend(api.class, Function.class, classloader, true)) {
        Class enclosing = cf.getEnclosingClass();
        if (functionMap.containsKey(enclosing)) {
            functionMap.get(enclosing).add(cf);
        } else {
            functionMap.put(enclosing, new ArrayList<Class<? extends Function>>());
            functionMap.get(enclosing).add(cf);
        }
    }
    ArrayList<Entry<Class<?>, ArrayList<Class<? extends Function>>>> functionEntryList = new ArrayList<>(functionMap.entrySet());
    Collections.sort(functionEntryList, new Comparator<Entry<Class<?>, ArrayList<Class<? extends Function>>>>() {

        @Override
        public int compare(Entry<Class<?>, ArrayList<Class<? extends Function>>> o1, Entry<Class<?>, ArrayList<Class<? extends Function>>> o2) {
            return o1.getKey().getName().compareTo(o2.getKey().getName());
        }
    });
    for (Entry<Class<?>, ArrayList<Class<? extends Function>>> e : functionEntryList) {
        Collections.sort(e.getValue(), new Comparator<Class<? extends Function>>() {

            @Override
            public int compare(Class<? extends Function> o1, Class<? extends Function> o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
    }
    if (!functionEntryList.isEmpty()) {
        fdocs.append("# Functions").append(nl);
    }
    for (Entry<Class<?>, ArrayList<Class<? extends Function>>> entry : functionEntryList) {
        Class enclosingClass = entry.getKey();
        String[] split = enclosingClass.getName().split("\\.");
        fdocs.append("## ").append(split[split.length - 1]).append(nl);
        try {
            Method docsMethod = enclosingClass.getMethod("docs", (Class[]) null);
            Object o = enclosingClass.newInstance();
            fdocs.append((String) docsMethod.invoke(o, (Object[]) null)).append(nl).append(nl);
        } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception) {
        }
        for (Class<? extends Function> cf : entry.getValue()) {
            Function f = cf.newInstance();
            if (f.appearInDocumentation()) {
                DocGen.DocInfo di = new DocGen.DocInfo(f.docs());
                String d = "### " + markdownEscape(di.ret) + " " + markdownEscape(f.getName()) + "(" + markdownEscape(di.originalArgs) + "):" + nl + convertWiki(di.topDesc != null ? di.topDesc : di.desc) + nl + convertWiki(di.extendedDesc != null ? nl + di.extendedDesc + nl : "");
                fdocs.append(d).append(nl);
            }
        }
    }
    // events
    HashMap<Class<?>, ArrayList<Class<? extends Event>>> eventMap = new HashMap<>();
    for (Class<? extends Event> ce : customDiscovery.loadClassesWithAnnotationThatExtend(api.class, Event.class, classloader, true)) {
        Class<?> enclosing = ce.getEnclosingClass();
        if (eventMap.containsKey(enclosing)) {
            eventMap.get(enclosing).add(ce);
        } else {
            eventMap.put(enclosing, new ArrayList<Class<? extends Event>>());
            eventMap.get(enclosing).add(ce);
        }
    }
    ArrayList<Entry<Class<?>, ArrayList<Class<? extends Event>>>> eventEntryList = new ArrayList<>(eventMap.entrySet());
    Collections.sort(eventEntryList, new Comparator<Entry<Class<?>, ArrayList<Class<? extends Event>>>>() {

        @Override
        public int compare(Entry<Class<?>, ArrayList<Class<? extends Event>>> o1, Entry<Class<?>, ArrayList<Class<? extends Event>>> o2) {
            return o1.getKey().getName().compareTo(o2.getKey().getName());
        }
    });
    for (Entry<Class<?>, ArrayList<Class<? extends Event>>> e : eventEntryList) {
        Collections.sort(e.getValue(), new Comparator<Class<? extends Event>>() {

            @Override
            public int compare(Class<? extends Event> o1, Class<? extends Event> o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
    }
    if (!eventEntryList.isEmpty()) {
        fdocs.append("# Events").append(nl);
    }
    for (Entry<Class<?>, ArrayList<Class<? extends Event>>> entry : eventEntryList) {
        Class enclosingClass = entry.getKey();
        String[] split = enclosingClass.getName().split("\\.");
        fdocs.append("## ").append(split[split.length - 1]).append(nl);
        try {
            Method docsMethod = enclosingClass.getMethod("docs", (Class[]) null);
            Object o = enclosingClass.newInstance();
            fdocs.append((String) docsMethod.invoke(o, (Object[]) null)).append(nl).append(nl);
        } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception) {
        }
        for (Class<? extends Event> ce : entry.getValue()) {
            Event e = ce.newInstance();
            Pattern p = Pattern.compile("\\{(.*?)\\} *?(.*?) *?\\{(.*?)\\} *?\\{(.*?)\\}");
            Matcher m = p.matcher(e.docs());
            if (m.find()) {
                String name = e.getName();
                String description = m.group(2).trim();
                String prefilter = DocGen.PrefilterData.Get(m.group(1).split("\\|"), DocGen.MarkupType.MARKDOWN);
                String eventData = DocGen.EventData.Get(m.group(3).split("\\|"), DocGen.MarkupType.MARKDOWN);
                String mutability = DocGen.MutabilityData.Get(m.group(4).split("\\|"), DocGen.MarkupType.MARKDOWN);
                // String manualTrigger = ManualTriggerData.Get(m.group(5).split("\\|"), DocGen.MarkupType.MARKDOWN);
                // String since = e.since().toString();
                fdocs.append("### ").append(markdownEscape(name)).append(nl);
                fdocs.append(description).append(nl);
                fdocs.append("#### Prefilters").append(nl).append(prefilter).append(nl);
                fdocs.append("#### Event Data").append(nl).append(eventData).append(nl);
                fdocs.append("#### Mutable Fields").append(nl).append(mutability).append(nl);
            }
        }
    }
    outputStream.write(fdocs.toString().getBytes("UTF-8"));
}
Also used : DynamicClassLoader(com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader) HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) URL(java.net.URL) Function(com.laytonsmith.core.functions.Function) Entry(java.util.Map.Entry) Pattern(java.util.regex.Pattern) Method(java.lang.reflect.Method) ClassDiscovery(com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery) InvocationTargetException(java.lang.reflect.InvocationTargetException) Event(com.laytonsmith.core.events.Event) ClassDiscoveryCache(com.laytonsmith.PureUtilities.ClassLoading.ClassDiscoveryCache)

Example 3 with Event

use of com.laytonsmith.core.events.Event in project CommandHelper by EngineHub.

the class ExtensionManager method Initialize.

/**
 * Initializes the extension manager. This operation is not necessarily required, and must be guaranteed to not run
 * more than once per ClassDiscovery object.
 *
 * @param cd the ClassDiscovery to use for loading files.
 */
public static void Initialize(ClassDiscovery cd) {
    extensions.clear();
    // Look in the extension folder for jars, add them to our class discover,
    // then initialize everything
    List<File> toProcess = new ArrayList<>();
    // Grab files from the cache if on Windows. Otherwise just load
    // directly from the stored locations.
    boolean onWindows = (OSUtils.GetOS() == OSUtils.OS.WINDOWS);
    if (onWindows) {
        toProcess.addAll(getFiles(CommandHelperFileLocations.getDefault().getExtensionCacheDirectory()));
    } else {
        for (File location : locations) {
            toProcess.addAll(getFiles(location));
        }
    }
    DynamicClassLoader dcl = new DynamicClassLoader();
    cd.setDefaultClassLoader(dcl);
    for (File f : toProcess) {
        if (f.getName().endsWith(".jar")) {
            try {
                // First, load it with our custom class loader
                URL jar = f.toURI().toURL();
                dcl.addJar(jar);
                cd.addDiscoveryLocation(jar);
                CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.DEBUG, "Loaded " + f.getAbsolutePath(), Target.UNKNOWN);
            } catch (MalformedURLException ex) {
                Static.getLogger().log(Level.SEVERE, null, ex);
            }
        }
    }
    // one found defines the internal name.
    for (ClassMirror<? extends AbstractExtension> extmirror : cd.getClassesWithAnnotationThatExtend(MSExtension.class, AbstractExtension.class)) {
        if (extmirror.equals(new ClassMirror<>(AbstractExtension.class))) {
            continue;
        }
        Extension ext;
        URL url = extmirror.getContainer();
        Class<? extends AbstractExtension> extcls;
        if (extmirror.getModifiers().isAbstract()) {
            Static.getLogger().log(Level.SEVERE, "Probably won't be able to" + " instantiate " + extmirror.getClassName() + ": The" + " class is marked as abstract! Will try anyway.");
        }
        try {
            extcls = extmirror.loadClass(dcl, true);
        } catch (Throwable ex) {
            // May throw anything, and kill the loading process.
            // Lets prevent that!
            Static.getLogger().log(Level.SEVERE, "Could not load class '" + extmirror.getClassName() + "'");
            ex.printStackTrace();
            continue;
        }
        try {
            ext = extcls.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            // Error, but skip this one, don't throw an exception ourselves, just log it.
            Static.getLogger().log(Level.SEVERE, "Could not instantiate " + extcls.getName() + ": " + ex.getMessage());
            continue;
        }
        ExtensionTracker trk = extensions.get(url);
        if (trk == null) {
            trk = new ExtensionTracker(url, cd, dcl);
            extensions.put(url, trk);
        }
        // use it.
        if (trk.identifier == null) {
            trk.identifier = ext.getName();
            try {
                trk.version = ext.getVersion();
            } catch (AbstractMethodError ex) {
                // getVersion() was added later. This is a temporary fix
                // to allow extension authors some time to update.
                // TODO: Remove this soon.
                trk.version = new SimpleVersion("0.0.0");
            }
        }
        trk.allExtensions.add(ext);
    }
    // Lets store info about the functions and events extensions have.
    // This will aide in gracefully unloading stuff later.
    Set<ClassMirror<?>> classes = cd.getClassesWithAnnotation(api.class);
    // Temp tracking for loading messages later on.
    List<String> events = new ArrayList<>();
    List<String> functions = new ArrayList<>();
    // and store the instances in their trackers.
    for (ClassMirror klass : classes) {
        URL url = klass.getContainer();
        if (cd.doesClassExtend(klass, Event.class) || cd.doesClassExtend(klass, Function.class)) {
            Class c;
            try {
                c = klass.loadClass(dcl, true);
            } catch (Throwable ex) {
                // May throw anything, and kill the loading process.
                // Lets prevent that!
                Static.getLogger().log(Level.SEVERE, "Could not load class '" + klass.getClassName() + "'");
                ex.printStackTrace();
                continue;
            }
            ExtensionTracker trk = extensions.get(url);
            if (trk == null) {
                trk = new ExtensionTracker(url, cd, dcl);
                extensions.put(url, trk);
            }
            // Instantiate, register and store.
            try {
                if (Event.class.isAssignableFrom(c)) {
                    Class<Event> cls = (Class<Event>) c;
                    if (klass.getModifiers().isAbstract()) {
                        // Abstract? Looks like they accidently @api'd
                        // a cheater class. We can't be sure that it is fully
                        // defined, so complain to the console.
                        CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.ERROR, "Class " + c.getName() + " in " + url + " is" + " marked as an event but is also abstract." + " Bugs might occur! Bug someone about this!", Target.UNKNOWN);
                    }
                    Event e = cls.newInstance();
                    events.add(e.getName());
                    trk.registerEvent(e);
                } else if (Function.class.isAssignableFrom(c)) {
                    Class<Function> cls = (Class<Function>) c;
                    if (klass.getModifiers().isAbstract()) {
                        // Abstract? Looks like they accidently @api'd
                        // a cheater class. We can't be sure that it is fully
                        // defined, so complain to the console.
                        CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.ERROR, "Class " + c.getName() + " in " + url + " is" + " marked as a function but is also abstract." + " Bugs might occur! Bug someone about this!", Target.UNKNOWN);
                    }
                    Function f = cls.newInstance();
                    functions.add(f.getName());
                    trk.registerFunction(f);
                }
            } catch (InstantiationException ex) {
                Static.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
            } catch (IllegalAccessException ex) {
                Static.getLogger().log(Level.SEVERE, null, ex);
            }
        }
    }
    // Lets print out the details to the console, if we are in debug mode.
    try {
        if (Prefs.DebugMode()) {
            Collections.sort(events);
            String eventString = StringUtils.Join(events, ", ", ", and ", " and ");
            Collections.sort(functions);
            String functionString = StringUtils.Join(functions, ", ", ", and ", " and ");
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded the following functions: " + functionString.trim());
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded " + functions.size() + " function" + (functions.size() == 1 ? "." : "s."));
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded the following events: " + eventString.trim());
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded " + events.size() + " event" + (events.size() == 1 ? "." : "s."));
        }
    } catch (Throwable e) {
    // Prefs weren't loaded, probably caused by running tests.
    }
}
Also used : DynamicClassLoader(com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader) MalformedURLException(java.net.MalformedURLException) ArrayList(java.util.ArrayList) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) URL(java.net.URL) CFunction(com.laytonsmith.core.constructs.CFunction) Function(com.laytonsmith.core.functions.Function) SimpleVersion(com.laytonsmith.PureUtilities.SimpleVersion) Event(com.laytonsmith.core.events.Event) File(java.io.File)

Example 4 with Event

use of com.laytonsmith.core.events.Event in project CommandHelper by EngineHub.

the class DocGen method events.

public static String events(MarkupType type) {
    Set<Class<?>> classes = ClassDiscovery.getDefaultInstance().loadClassesWithAnnotation(api.class);
    Set<Documentation> list = new TreeSet<Documentation>();
    for (Class<?> c : classes) {
        if (Event.class.isAssignableFrom(c) && Documentation.class.isAssignableFrom(c)) {
            try {
                // First, we have to instatiate the event.
                Constructor<Event> cons = (Constructor<Event>) c.getConstructor();
                Documentation docs = cons.newInstance();
                list.add(docs);
            } catch (Exception ex) {
                StreamUtils.GetSystemErr().println("Could not get documentation for " + c.getSimpleName());
            }
        }
    }
    StringBuilder doc = new StringBuilder();
    if (type == MarkupType.HTML) {
        doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as" + " a player logging in, or a player breaking a block. See the documentation on events for" + " more information" + "<table><thead><tr><th>Name</th><th>Description</th><th>Prefilters</th>" + "<th>Event Data</th><th>Mutable Fields</th><th>Since</th></thead><tbody>");
    } else if (type == MarkupType.WIKI) {
        doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as" + " a player logging in, or a player breaking a block. See the [[CommandHelper/Events|documentation on events]] for" + " more information<br />\n\n");
        doc.append("{| width=\"100%\" cellspacing=\"1\" cellpadding=\"1\" border=\"1\" class=\"wikitable\"\n" + "|-\n" + "! scope=\"col\" width=\"7%\" | Event Name\n" + "! scope=\"col\" width=\"36%\" | Description\n" + "! scope=\"col\" width=\"18%\" | Prefilters\n" + "! scope=\"col\" width=\"18%\" | Event Data\n" + "! scope=\"col\" width=\"18%\" | Mutable Fields\n" + "! scope=\"col\" width=\"3%\" | Since\n");
    } else if (type == MarkupType.TEXT) {
        doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as" + " a player logging in, or a player breaking a block. See the documentation on events for" + " more information\n\n\n");
    }
    Pattern p = Pattern.compile("\\{(.*?)\\} *?(.*?) *?\\{(.*?)\\} *?\\{(.*?)\\}");
    for (Documentation d : list) {
        Matcher m = p.matcher(d.docs());
        if (m.find()) {
            String name = d.getName();
            String description = m.group(2).trim();
            String prefilter = PrefilterData.Get(m.group(1).split("\\|"), type);
            String eventData = EventData.Get(m.group(3).split("\\|"), type);
            String mutability = MutabilityData.Get(m.group(4).split("\\|"), type);
            // String manualTrigger = ManualTriggerData.Get(m.group(5).split("\\|"), type);
            String since = d.since().toString();
            if (type == MarkupType.HTML) {
                doc.append("<tr><td style=\"vertical-align:top\">").append(name).append("</td><td style=\"vertical-align:top\">").append(description).append("</td><td style=\"vertical-align:top\">").append(prefilter).append("</td><td style=\"vertical-align:top\">").append(eventData).append("</td><td style=\"vertical-align:top\">").append(mutability).append("</td><td style=\"vertical-align:top\">").append(since).append("</td></tr>\n");
            } else if (type == MarkupType.WIKI) {
                doc.append("|-\n" + "! scope=\"row\" | [[CommandHelper/Event API/").append(name).append("|").append(name).append("]]\n" + "| ").append(description).append("\n" + "| ").append(prefilter).append("\n" + "| ").append(eventData).append("\n" + "| ").append(mutability).append("\n" + "| ").append(since).append("\n");
            } else if (type == MarkupType.TEXT) {
                doc.append("Name: ").append(name).append("\nDescription: ").append(description).append("\nPrefilters:\n").append(prefilter).append("\nEvent Data:\n").append(eventData).append("\nMutable Fields:\n").append(mutability).append("\nSince: ").append(since).append("\n\n");
            }
        }
    }
    if (type == MarkupType.HTML) {
        doc.append("</tbody></table>\n");
    } else if (type == MarkupType.WIKI) {
        doc.append("|}\n");
    }
    if (type == MarkupType.HTML) {
        doc.append("" + "<h2>Errors in documentation</h2>\n" + "<em>Please note that this documentation is generated automatically," + " if you notice an error in the documentation, please file a bug report for the" + " plugin itself!</em>\n");
    } else if (type == MarkupType.WIKI) {
        doc.append("" + "===Errors in documentation===\n" + "''Please note that this documentation is generated automatically," + " if you notice an error in the documentation, please file a bug report for the" + " plugin itself!'' For information on undocumented functions, see [[CommandHelper/Sandbox|this page]]\n\n{{LearningTrail}}\n");
    }
    return doc.toString();
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) Constructor(java.lang.reflect.Constructor) Documentation(com.laytonsmith.core.Documentation) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) InvocationTargetException(java.lang.reflect.InvocationTargetException) TreeSet(java.util.TreeSet) Event(com.laytonsmith.core.events.Event)

Example 5 with Event

use of com.laytonsmith.core.events.Event in project CommandHelper by EngineHub.

the class SiteDeploy method deployEventAPI.

private void deployEventAPI() {
    generateQueue.submit(new Runnable() {

        @Override
        public void run() {
            try {
                Set<Class<? extends Event>> eventClasses = new TreeSet<>(new Comparator<Class<? extends Event>>() {

                    @Override
                    public int compare(Class<? extends Event> o1, Class<? extends Event> o2) {
                        Event f1 = ReflectionUtils.instantiateUnsafe(o1);
                        Event f2 = ReflectionUtils.instantiateUnsafe(o2);
                        return f1.getName().compareTo(f2.getName());
                    }
                });
                eventClasses.addAll(ClassDiscovery.getDefaultInstance().loadClassesWithAnnotationThatExtend(api.class, Event.class));
                // A map of where it maps the enclosing class to the list of event rows, which contains a list of table cells.
                Map<Class<?>, List<List<String>>> data = new TreeMap<>(new Comparator<Class<?>>() {

                    @Override
                    public int compare(Class<?> o1, Class<?> o2) {
                        return o1.getCanonicalName().compareTo(o2.getCanonicalName());
                    }
                });
                for (Class<? extends Event> eventClass : eventClasses) {
                    if (!data.containsKey(eventClass.getEnclosingClass())) {
                        data.put(eventClass.getEnclosingClass(), new ArrayList<>());
                    }
                    List<List<String>> d = data.get(eventClass.getEnclosingClass());
                    List<String> c = new ArrayList<>();
                    // event name, description, prefilters, data, mutable
                    final Event e;
                    try {
                        e = ReflectionUtils.instantiateUnsafe(eventClass);
                    } catch (ReflectionUtils.ReflectionException ex) {
                        throw new RuntimeException("While trying to construct " + eventClass + ", got the following", ex);
                    }
                    final DocGen.EventDocInfo edi = new DocGen.EventDocInfo(e.docs(), e.getName());
                    if (e.since().equals(CHVersion.V0_0_0)) {
                        // Don't add these
                        continue;
                    }
                    c.add(e.getName());
                    c.add(edi.description);
                    List<String> pre = new ArrayList<>();
                    if (!edi.prefilter.isEmpty()) {
                        for (DocGen.EventDocInfo.PrefilterData pdata : edi.prefilter) {
                            pre.add("<p><strong>" + pdata.name + "</strong>: " + pdata.formatDescription(DocGen.MarkupType.HTML) + "</p>");
                        }
                    }
                    c.add(StringUtils.Join(pre, ""));
                    List<String> ed = new ArrayList<>();
                    if (!edi.eventData.isEmpty()) {
                        for (DocGen.EventDocInfo.EventData edata : edi.eventData) {
                            ed.add("<p><strong>" + edata.name + "</strong>" + (!edata.description.isEmpty() ? ": " + edata.description : "") + "</p>");
                        }
                    }
                    c.add(StringUtils.Join(ed, ""));
                    List<String> mut = new ArrayList<>();
                    if (!edi.mutability.isEmpty()) {
                        for (DocGen.EventDocInfo.MutabilityData mdata : edi.mutability) {
                            mut.add("<p><strong>" + mdata.name + "</strong>" + (!mdata.description.isEmpty() ? ": " + mdata.description : "") + "</p>");
                        }
                    }
                    c.add(StringUtils.Join(mut, ""));
                    d.add(c);
                }
                // data is now constructed.
                StringBuilder b = new StringBuilder();
                b.append("<ul id=\"TOC\">");
                for (Class<?> clazz : data.keySet()) {
                    b.append("<li><a href=\"#").append(clazz.getSimpleName()).append("\">").append(clazz.getSimpleName()).append("</a></li>");
                }
                b.append("</ul>\n");
                for (Map.Entry<Class<?>, List<List<String>>> e : data.entrySet()) {
                    Class<?> clazz = e.getKey();
                    List<List<String>> clazzData = e.getValue();
                    if (clazzData.isEmpty()) {
                        // If there are no events in the class, don't display it.
                        continue;
                    }
                    try {
                        b.append("== ").append(clazz.getSimpleName()).append(" ==\n");
                        String docs = (String) ReflectionUtils.invokeMethod(clazz, null, "docs");
                        b.append("<div>").append(docs).append("</div>\n\n");
                        b.append("{|\n|-\n");
                        b.append("! scope=\"col\" width=\"7%\" | Event Name\n" + "! scope=\"col\" width=\"30%\" | Description\n" + "! scope=\"col\" width=\"20%\" | Prefilters\n" + "! scope=\"col\" width=\"25%\" | Event Data\n" + "! scope=\"col\" width=\"18%\" | Mutable Fields\n");
                        for (List<String> row : clazzData) {
                            b.append("|-");
                            b.append("\n");
                            for (String cell : row) {
                                b.append("| ").append(cell).append("\n");
                            }
                        }
                        b.append("|}\n");
                        b.append("<p><a href=\"#TOC\">Back to top</a></p>\n");
                    } catch (Error ex) {
                        Logger.getLogger(SiteDeploy.class.getName()).log(Level.SEVERE, "While processing " + clazz + " got:", ex);
                    }
                }
                writePage("Event API", b.toString(), "Event_API.html", Arrays.asList(new String[] { "API", "events" }), "A list of all " + Implementation.GetServerType().getBranding() + " events");
                currentGenerateTask.addAndGet(1);
            } catch (Error ex) {
                ex.printStackTrace(System.err);
            }
        }
    });
    totalGenerateTasks.addAndGet(1);
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) DocGen(com.laytonsmith.tools.docgen.DocGen) Comparator(java.util.Comparator) Event(com.laytonsmith.core.events.Event) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Aggregations

Event (com.laytonsmith.core.events.Event)6 ArrayList (java.util.ArrayList)4 Function (com.laytonsmith.core.functions.Function)3 HashMap (java.util.HashMap)3 Matcher (java.util.regex.Matcher)3 Pattern (java.util.regex.Pattern)3 DynamicClassLoader (com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader)2 Constructor (java.lang.reflect.Constructor)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 URL (java.net.URL)2 Map (java.util.Map)2 TreeSet (java.util.TreeSet)2 ClassDiscovery (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery)1 ClassDiscoveryCache (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscoveryCache)1 ClassMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror)1 SimpleVersion (com.laytonsmith.PureUtilities.SimpleVersion)1 Documentation (com.laytonsmith.core.Documentation)1 CFunction (com.laytonsmith.core.constructs.CFunction)1 AbstractEvent (com.laytonsmith.core.events.AbstractEvent)1 EventMixinInterface (com.laytonsmith.core.events.EventMixinInterface)1