-
Notifications
You must be signed in to change notification settings - Fork 4
Merged in the latest changes to the "javadoc" command from OakBot. #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5614cd6
9bc9652
63ebe50
8c04015
0577476
c2cccbf
01c8aaa
edc2e3b
f115c3a
036e7d9
1e80b94
2abd9b7
c3fb661
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,23 @@ | ||
Put a ZIP file here named "java8.zip" containing Java's Javadocs (or where ever "BotConfig.JAVADOCS_DIR" points to) | ||
This folder contains ZIP files generated by OakbotDoclet. | ||
|
||
The ZIP file should contain the files that are in the "api" directory of the "Documentation" download, found here: | ||
http://www.oracle.com/technetwork/java/javase/documentation/jdk8-doc-downloads-2133158.html | ||
* Each ZIP file contains a collection of XML files, which contain parsed Javadoc information of a particular library. | ||
* Each XML file contains the Javadoc information of a single class. | ||
* The ZIP file also contains a "info.xml" file, which contains information about the library itself. | ||
|
||
Make sure that a file called "allclasses-frames.html" is at the root of the ZIP. | ||
======================= | ||
|
||
I don't want to commit the real Javadoc file to version control, due to its large file size (~50MB), so I've committed a smaller, sample file instead. | ||
To generate a ZIP file: | ||
|
||
1. Clone and open the OakBot project: http://github.com/mangstadt/OakBot | ||
2. Compile the OakbotDoclet class. You will need to include the JVM's "tools.jar" file on the classpath during compilation. This file can be found at "$JAVA_HOME/lib/tools.jar" | ||
3. Tweak the "build-zip.sh" file as necessary and then execute it. Note that you'll need a copy of the library's source code on your computer. | ||
|
||
======================= | ||
|
||
I don't want to commit the ZIP for the Java 8 API to version control, due to its large file size (~6MB), so I've committed a smaller, sample file instead. | ||
The sample ZIP file contains just a single class (java.lang.String). | ||
|
||
ZIP files for various libraries (including the core Java 8 API) can be downloaded here: | ||
https://www.dropbox.com/sh/xkf7kua3hzd8xvo/AAC1sOkVTNUE2MKPAXTm28bna?dl=0 | ||
|
||
-Michael |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ public class DefaultBot extends AbstractBot implements Subscribable<CommandHandl | |
protected final ChatInterface chatInterface; | ||
|
||
protected final Set<CommandHandle> commands = new HashSet<>(); | ||
protected final Set<CommandHandle> listeners = new HashSet<>(); | ||
|
||
public DefaultBot(ChatInterface chatInterface) { | ||
this.chatInterface = chatInterface; | ||
|
@@ -52,6 +53,8 @@ private void processMessageQueue() { | |
} | ||
|
||
private void processMessage(final ChatMessage chatMessage) { | ||
listeners.stream().map(l -> l.execute(chatMessage)).filter(l -> null != l).forEach(result -> chatInterface.sendMessage(SeChatDescriptor.buildSeChatDescriptorFrom(chatMessage), result)); | ||
|
||
final String trigger = AppContext.INSTANCE.get(BotConfig.class).getTrigger(); | ||
if ( !chatMessage.getMessage().startsWith(trigger)) { return; } | ||
|
||
|
@@ -62,14 +65,23 @@ private void processMessage(final ChatMessage chatMessage) { | |
public Set<CommandHandle> getCommands() { | ||
return Collections.unmodifiableSet(commands); | ||
} | ||
|
||
public Set<CommandHandle> getListeners(){ | ||
return Collections.unmodifiableSet(listeners); | ||
} | ||
|
||
@Override | ||
public void subscribe(CommandHandle subscriber) { | ||
commands.add(subscriber); | ||
if (subscriber.getName() == null){ | ||
listeners.add(subscriber); | ||
} else { | ||
commands.add(subscriber); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one smells... See above comments about extracting a separate bot. It shouldn't be that much of a problem to set OakBot up as separate class There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, it is very smelly. Maybe add a different interface for listerners, like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be interesting, yes. This would be a step to extracting OakBot, though. Your call ;) |
||
} | ||
|
||
@Override | ||
public void unSubscribe(CommandHandle subscriber) { | ||
listeners.remove(subscriber); | ||
commands.remove(subscriber); | ||
} | ||
|
||
|
@@ -79,7 +91,9 @@ public void shutdown() { | |
|
||
@Override | ||
public Collection<CommandHandle> getSubscriptions() { | ||
return Collections.unmodifiableCollection(commands); | ||
Set<CommandHandle> set = new HashSet<CommandHandle>(commands); | ||
set.addAll(listeners); | ||
return set; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,187 @@ | ||
package com.gmail.inverseconduit.javadoc; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import com.google.common.collect.ImmutableMultimap; | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.common.collect.Multimap; | ||
|
||
/** | ||
* Holds the Javadoc info of a class. | ||
* @author Michael Angstadt | ||
*/ | ||
public class ClassInfo { | ||
private final String fullName; | ||
private final ClassName name; | ||
private final ClassName superClass; | ||
private final String description; | ||
private final String url; | ||
private final List<String> modifiers; | ||
private final Set<String> modifiers; | ||
private final Set<ClassName> interfaces; | ||
private final Multimap<String, MethodInfo> methods; | ||
private final boolean deprecated; | ||
private final LibraryZipFile zipFile; | ||
|
||
private ClassInfo(Builder builder) { | ||
name = builder.name; | ||
superClass = builder.superClass; | ||
description = builder.description; | ||
modifiers = builder.modifiers.build(); | ||
interfaces = builder.interfaces.build(); | ||
methods = builder.methods.build(); | ||
deprecated = builder.deprecated; | ||
zipFile = builder.zipFile; | ||
} | ||
|
||
public ClassInfo(String fullName, String description, String url, List<String> modifiers, boolean deprecated) { | ||
this.fullName = fullName; | ||
this.description = description; | ||
this.url = url; | ||
this.modifiers = modifiers; | ||
this.deprecated = deprecated; | ||
/** | ||
* Gets the name of the class. | ||
* @return the class name | ||
*/ | ||
public ClassName getName() { | ||
return name; | ||
} | ||
|
||
/** | ||
* Gets the class's fully-qualified name. | ||
* @return the fully-qualified name (e.g. "java.lang.String") | ||
* Gets the name of the class's parent class. | ||
* @return the parent class name or null if it doesn't have one | ||
*/ | ||
public String getFullName() { | ||
return fullName; | ||
public ClassName getSuperClass() { | ||
return superClass; | ||
} | ||
|
||
/** | ||
* Gets the class's description. | ||
* @return the class description, formatted in SO Chat's markdown language | ||
* Gets the class description. | ||
* @return the class description (in SO-Chat markdown) | ||
*/ | ||
public String getDescription() { | ||
return description; | ||
} | ||
|
||
/** | ||
* Gets the URL where this class's Javadocs can be viewed online. | ||
* @return the URL or null if unknown | ||
* Gets the URL to this class's Javadoc page (with frames). | ||
* @return the URL or null if no base URL was given | ||
*/ | ||
public String getFrameUrl() { | ||
return zipFile.getFrameUrl(this); | ||
} | ||
|
||
/** | ||
* Gets the URL to this class's Javadoc page (without frames). | ||
* @return the URL or null if no base URL was given | ||
*/ | ||
public String getUrl() { | ||
return url; | ||
return zipFile.getUrl(this); | ||
} | ||
|
||
/** | ||
* Gets the modifiers of this class. | ||
* @return the modifiers (e.g. "public", "final", "class") | ||
* Gets the class modifiers. | ||
* @return the class modifiers (e.g. "public, final") | ||
*/ | ||
public List<String> getModifiers() { | ||
public Collection<String> getModifiers() { | ||
return modifiers; | ||
} | ||
|
||
/** | ||
* Gets whether the class is deprecated or not. | ||
* Gets the names of the interfaces that the class implements. | ||
* @return the class's interfaces | ||
*/ | ||
public Collection<ClassName> getInterfaces() { | ||
return interfaces; | ||
} | ||
|
||
/** | ||
* Gets info on all of the methods that have the given name. | ||
* @param name the method name (case insensitive) | ||
* @return the methods | ||
*/ | ||
public Collection<MethodInfo> getMethod(String name) { | ||
return methods.get(name.toLowerCase()); | ||
} | ||
|
||
/** | ||
* Gets the class's methods. | ||
* @return the class's methods | ||
*/ | ||
public Collection<MethodInfo> getMethods() { | ||
return methods.values(); | ||
} | ||
|
||
/** | ||
* Determines whether the class is deprecated or not. | ||
* @return true if it's deprecated, false if not | ||
*/ | ||
public boolean isDeprecated() { | ||
return deprecated; | ||
} | ||
|
||
/** | ||
* Gets the ZIP file that the class's parsed Javadoc info is stored in. | ||
* @return the ZIP file | ||
*/ | ||
public LibraryZipFile getZipFile() { | ||
return zipFile; | ||
} | ||
|
||
/** | ||
* Builds new instances of {@link ClassInfo}. | ||
*/ | ||
public static class Builder { | ||
private ClassName name; | ||
private ClassName superClass; | ||
private String description; | ||
private ImmutableSet.Builder<String> modifiers = ImmutableSet.builder(); | ||
private ImmutableSet.Builder<ClassName> interfaces = ImmutableSet.builder(); | ||
private ImmutableMultimap.Builder<String, MethodInfo> methods = ImmutableMultimap.builder(); | ||
private boolean deprecated = false; | ||
private LibraryZipFile zipFile; | ||
|
||
public Builder name(String full, String simple) { | ||
this.name = new ClassName(full, simple); | ||
return this; | ||
} | ||
|
||
public Builder description(String description) { | ||
this.description = description; | ||
return this; | ||
} | ||
|
||
public Builder superClass(String superClass) { | ||
this.superClass = new ClassName(superClass); | ||
return this; | ||
} | ||
|
||
public Builder modifiers(List<String> modifiers) { | ||
this.modifiers.addAll(modifiers); | ||
return this; | ||
} | ||
|
||
public Builder interface_(String interface_) { | ||
interfaces.add(new ClassName(interface_)); | ||
return this; | ||
} | ||
|
||
public Builder interfaces(List<ClassName> interfaces) { | ||
this.interfaces.addAll(interfaces); | ||
return this; | ||
} | ||
|
||
public Builder method(MethodInfo method) { | ||
this.methods.put(method.getName().toLowerCase(), method); | ||
return this; | ||
} | ||
|
||
public Builder deprecated(boolean deprecated) { | ||
this.deprecated = deprecated; | ||
return this; | ||
} | ||
|
||
public Builder zipFile(LibraryZipFile zipFile) { | ||
this.zipFile = zipFile; | ||
return this; | ||
} | ||
|
||
public ClassInfo build() { | ||
return new ClassInfo(this); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be interesting to get oakBot a completely separate bot, given how he internally works different...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this isn't a merge of OakBot into JavaBot, it's a merge of OakBot's "javadoc" command into JavaBot. :P
The reason I added the "listeners" Set is because I need a way to listen for numbers that people type into the chat.