Package redis.redisgen

Source Code of redis.redisgen.Main

package redis.redisgen;

import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheException;
import com.github.mustachejava.MustacheFactory;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Multimaps;
import com.sampullara.cli.Args;
import com.sampullara.cli.Argument;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.MappingJsonFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
* Generate client code for redis based on the protocol.
* <p/>
* User: sam
* Date: 11/5/11
* Time: 9:10 PM
*/
@SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
public class Main {

  @Argument(alias = "l")
  private static String language = "java";

  @Argument(alias = "p")
  private static String pkg = "redis.client";

  @Argument(alias = "d", required = true)
  private static File dest;

  @Argument(alias = "t")
  private static String template = "client";

  @Argument(alias = "n")
  private static String className = "RedisClient";

  private static Set<String> keywords = new HashSet<String>() {{
    add("type");
    add("object");
  }};

  @SuppressWarnings("ResultOfMethodCallIgnored")
  public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException, XPathExpressionException, MustacheException {
    try {
      Args.parse(Main.class, args);
    } catch (IllegalArgumentException e) {
      Args.usage(Main.class);
      System.exit(1);
    }

    MustacheFactory mb = new DefaultMustacheFactory("templates/" + language) {
      @Override
      public void encode(String value, Writer writer) {
        try {
          writer.write(value);
        } catch (IOException e) {
          throw new MustacheException();
        }
      }
    };
    Mustache mustache = mb.compile(template + ".txt");

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    XPathFactory xpf = XPathFactory.newInstance();
    final DocumentBuilder db = dbf.newDocumentBuilder();
    final XPathExpression replyX = xpf.newXPath().compile("//a");
    final Properties cache = new Properties();
    File cacheFile = new File("cache");
    if (cacheFile.exists()) {
      cache.load(new FileInputStream(cacheFile));
    }

    Set<String> ungenerated = new HashSet<String>(
            Arrays.asList(
                    "MULTI", "EXEC", "DISCARD", // Transactions
                    "PSUBSCRIBE", "SUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", // subscriptions
                    "AUTH" // authentication
            )
    );
    final Set<String> genericReply = new HashSet<String>(Arrays.asList(
            "SORT", // Can return an integer reply
            "ZRANK", "ZREVRANK", // Two different return values
            "SRANDMEMBER", // Can return a bulk or multibulk reply depending on count
            "BRPOPLPUSH" // If the timeout occurs it returns a Nil multi-bulk reply instead of a bulk reply
    ));
    final Set<String> multiples = new HashSet<String>(Arrays.asList(
            "ZADD"
    ));
    JsonFactory jf = new MappingJsonFactory();
    JsonParser jsonParser = jf.createJsonParser(new URL("https://raw.github.com/antirez/redis-doc/master/commands.json"));
    final JsonNode commandNodes = jsonParser.readValueAsTree();
    Iterator<String> fieldNames = commandNodes.getFieldNames();
    ImmutableListMultimap<String,String> group = Multimaps.index(fieldNames,
            new Function<String, String>() {
              @Override
              public String apply(String s) {
                return commandNodes.get(s).get("group").asText();
              }
            });
    List<Object> commands = new ArrayList<Object>();
    for (Map.Entry<String, String> entry : group.entries()) {
      String key = entry.getKey();
      final String groupName = key.substring(0, 1).toUpperCase() + key.substring(1);
      final String command = entry.getValue();
      if (ungenerated.contains(command)) continue;
      final boolean splitCommand = command.contains(" ");
      final String safeCommand = command.replace(" ", "_");
      String cacheReply = cache.getProperty(command.toLowerCase());
      if (cacheReply == null) {
        final Document detail = db.parse("http://query.yahooapis.com/v1/public/yql/javarants/redisreply?url=" + URLEncoder.encode("http://redis.io/commands/" + safeCommand.toLowerCase(), "utf-8"));
        cacheReply = replyX.evaluate(detail).replaceAll("[- ]", "").replaceAll("reply", "Reply").replaceAll("bulk", "Bulk").replaceAll("Statuscode", "Status");
        cache.setProperty(safeCommand.toLowerCase(), cacheReply);
        cache.store(new FileWriter(cacheFile), "# Updated " + new Date());
      }
      final String finalReply = cacheReply;
      final JsonNode commandNode = commandNodes.get(command);
      commands.add(new Object() {
        String group = groupName;
        boolean split_command = splitCommand;
        String name = safeCommand;
        String name1 = splitCommand ? name.substring(0, name.indexOf("_")) : name;
        String name2 = splitCommand ? name.substring(name.indexOf("_") + 1) : "";
        String comment = commandNode.get("summary").getTextValue();
        boolean generic = finalReply.equals("") || genericReply.contains(name);
        String reply = generic ? "Reply" : finalReply;
        String version = commandNode.get("since").getTextValue();
        boolean hasOptional = false;
        boolean hasMultiple = false;
        List<String> skipped = new ArrayList<String>();
        boolean varargs() {
          return (hasMultiple || hasOptional);
        }

        boolean usearray = false;
        List<Object> arguments = new ArrayList<Object>();

        int base_length() {
          return arguments.size() - (hasMultiple ? 1 : 0);
        }

        {
          JsonNode argumentArray = commandNode.get("arguments");
          if (argumentArray != null) {
            if (argumentArray.size() > 3) {
              usearray = true;
            }
            boolean first = true;
            int argNum = 0;
            if (multiples.contains(name)) {
              arguments.add(new Object() {
                boolean first = true;
                boolean multiple = true;
                String typename = "Object";
                String name = "args";
              });
            } else {
              for (final JsonNode argumentNode : argumentArray) {
                JsonNode nameNodes = argumentNode.get("name");
                final String argName;
                if (nameNodes.isArray()) {
                  boolean f = true;
                  StringBuilder sb = new StringBuilder();
                  for (JsonNode nameNode : nameNodes) {
                    if (!f) {
                      sb.append("_or_");
                    }
                    f = false;
                    String textValue = nameNode.getTextValue();
                    sb.append(textValue);
                  }
                  argName = sb.toString();
                } else {
                  argName = nameNodes.getTextValue();
                }
                final boolean finalFirst = first;
                final int finalArgNum = argNum;
                final boolean isMultiple = argumentNode.get("multiple") != null || argumentNode.get("command") != null;
                final boolean isOptional = argumentNode.get("optional") != null;
                if (isOptional) hasOptional = true;
                if (isMultiple) hasMultiple = true;
                final int finalArgNum1 = argNum;
                arguments.add(new Object() {
                  int arg_num = finalArgNum1;
                  boolean first = finalFirst;
                  boolean multiple = isMultiple;
                  String typename = "Object";
                  String name() {
                    String name = (argName + finalArgNum).replaceAll("[- :]", "_");
                    for (String s : skipped) {
                      name = s + "_" + name;
                    }
                    return name;
                  }
                  Boolean optional = isOptional;
                  boolean skip() {
                    boolean skip = hasMultiple && isOptional && !isMultiple;
                    if (skip) {
                      skipped.add(argName);
                    }
                    return skip;
                  }
                });
                if (isMultiple) {
                  usearray = true;
                }
                first = false;
                argNum++;
                if (isMultiple) break;
              }
            }
          }
        }

        String methodname = safeCommand.toLowerCase();
        String quote = keywords.contains(methodname) ? "`" : "";
      });
    }

    Map<String, Object> ctx = new HashMap<String, Object>();
    ctx.put("commands", commands);
    File base = new File(dest, pkg.replace(".", "/"));
    base.mkdirs();
    mustache.execute(new FileWriter(new File(base, className + "." + language)), ctx).close();
  }
}
TOP

Related Classes of redis.redisgen.Main

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.