summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/support/texosquery/java/QueryAction.java')
-rw-r--r--Master/texmf-dist/source/support/texosquery/java/QueryAction.java448
1 files changed, 448 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/support/texosquery/java/QueryAction.java b/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
new file mode 100644
index 00000000000..b50e65cc3ad
--- /dev/null
+++ b/Master/texmf-dist/source/support/texosquery/java/QueryAction.java
@@ -0,0 +1,448 @@
+/*
+ Copyright (C) 2016 Nicola L.C. Talbot
+ www.dickimaw-books.com
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either version 1.3
+ of this license or (at your option) any later version.
+ The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of LaTeX
+ version 2005/12/01 or later.
+*/
+package com.dickimawbooks.texosquery;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Class representing an action to be performed by the application.
+ * @since 1.2
+ */
+public abstract class QueryAction implements Serializable
+{
+ public QueryAction()
+ {
+ }
+
+ public QueryAction(String longForm, QueryActionType type,
+ String description)
+ {
+ this(longForm, null, 0, 0, "", type, description);
+ }
+
+ public QueryAction(String longForm, QueryActionType type,
+ String description, int minCompat)
+ {
+ this(longForm, null, 0, 0, "", type, description, minCompat);
+ }
+
+ public QueryAction(String longForm, String shortForm,
+ QueryActionType type, String description)
+ {
+ this(longForm, shortForm, 0, 0, "", type, description);
+ }
+
+ public QueryAction(String longForm, String shortForm,
+ QueryActionType type, String description, int minCompat)
+ {
+ this(longForm, shortForm, 0, 0, "", type, description, minCompat);
+ }
+
+ public QueryAction(String longForm, String shortForm, String syntax,
+ QueryActionType type, String description)
+ {
+ this(longForm, shortForm, 0, 0, syntax, type, description);
+ }
+
+ public QueryAction(String longForm, String shortForm,
+ int numOptional, int numRequired, String syntax,
+ QueryActionType type, String description)
+ {
+ this(longForm, shortForm, numOptional, numRequired,
+ syntax, type, description, 0);
+ }
+
+ public QueryAction(String longForm, String shortForm,
+ int numOptional, int numRequired, String syntax,
+ QueryActionType type, String description, int minCompat)
+ {
+ if (longForm != null)
+ {
+ longName = "--"+longForm;
+ }
+
+ if (shortForm != null)
+ {
+ shortName = "-"+shortForm;
+ }
+
+ optional = numOptional;
+ required = numRequired;
+
+ this.syntax = syntax;
+ this.type = type;
+ this.description = description;
+ this.minCompatibility = minCompat;
+ }
+
+ public boolean isAction(String name)
+ {
+ return name.equals(shortName) || name.equals(longName)
+ || (longName != null && name.startsWith(longName+"="));
+ }
+
+ public int parseArgs(String[] args, int index)
+ throws IllegalArgumentException
+ {
+ if (required > 0)
+ {
+ requiredArgs = new String[required];
+ }
+
+ if (args[index].startsWith(longName+"="))
+ {
+ int idx = args[index].indexOf("=")+1;
+ invokedName = longName;
+
+ if (idx == args[index].length())
+ {
+ if (required == 1)
+ {
+ requiredArgs[0] = "";
+ }
+ else
+ {
+ throw new IllegalArgumentException(String.format(
+ "Invalid syntax for action '%s'.%nExpected: %s",
+ invokedName, getUsage(invokedName)));
+ }
+
+ return index+1;
+ }
+
+ String[] sp;
+
+ if (required+optional > 1)
+ {
+ sp = args[index].substring(idx).split(" ");
+ }
+ else
+ {
+ sp = new String[]{args[index].substring(idx)};
+ }
+
+ idx = 0;
+
+ for (int i = 0; i < required; i++)
+ {
+ if (i >= sp.length)
+ {
+ throw new IllegalArgumentException(String.format(
+ "Invalid syntax for action '%s'.%nExpected: %s",
+ invokedName, getUsage(invokedName)));
+ }
+
+ requiredArgs[i] = sp[idx++];
+ }
+
+ optionalProvided = 0;
+
+ if (optional > 0)
+ {
+ optionalArgs = new String[optional];
+ }
+
+ for (int i = 0; i < optional; i++)
+ {
+ if (idx >= sp.length)
+ {
+ // no optional arguments, skip
+ break;
+ }
+
+ optionalArgs[optionalProvided++] = sp[idx++];
+ }
+
+ return index+1;
+ }
+ else
+ {
+ invokedName = args[index++];
+
+ for (int i = 0; i < required; i++)
+ {
+ if (index >= args.length)
+ {
+ throw new IllegalArgumentException(String.format(
+ "Invalid syntax for action '%s'.%nExpected: %s",
+ invokedName, getUsage(invokedName)));
+ }
+
+ requiredArgs[i] = args[index++];
+ }
+
+ optionalProvided = 0;
+
+ if (optional > 0)
+ {
+ optionalArgs = new String[optional];
+ }
+
+ for (int i = 0; i < optional; i++)
+ {
+ if (index >= args.length || args[index].startsWith("-"))
+ {
+ // no optional arguments, skip
+ break;
+ }
+
+ optionalArgs[optionalProvided++] = args[index++];
+ }
+ }
+
+ return index;
+ }
+
+ public int providedOptionCount()
+ {
+ return optionalProvided;
+ }
+
+ public String getOptionalArgument(int index)
+ {
+ return index < optionalArgs.length ? optionalArgs[index] : null;
+ }
+
+ public String getRequiredArgument(int index)
+ {
+ return requiredArgs[index];
+ }
+
+ public String getInvocation()
+ {
+ StringBuilder builder = new StringBuilder(getInvokedName());
+
+ if (requiredArgs != null)
+ {
+ for (String arg : requiredArgs)
+ {
+ if (arg.contains(" "))
+ {
+ builder.append(String.format(" '%s'",
+ arg.replaceAll("'", "\\\\'")));
+ }
+ else
+ {
+ builder.append(String.format(" %s", arg));
+ }
+ }
+ }
+
+ if (optionalArgs != null)
+ {
+ for (String arg : optionalArgs)
+ {
+ if (arg == null) continue;
+
+ if (arg.contains(" "))
+ {
+ builder.append(String.format(" '%s'",
+ arg.replaceAll("'", "\\\\'")));
+ }
+ else
+ {
+ builder.append(String.format(" %s", arg));
+ }
+ }
+ }
+
+ return builder.toString();
+ }
+
+ public String getInvokedName()
+ {
+ return invokedName;
+ }
+
+ public QueryActionType getType()
+ {
+ return type;
+ }
+
+ public String getUsage(String name)
+ {
+ return String.format("%s%s",
+ name, syntax == null || "".equals(syntax) ? "" : " "+syntax);
+ }
+
+ /**
+ * Formats the description to fit maximum of 80 character line
+ * width.
+ */
+ private String formatDescription()
+ {
+ int n = description.length();
+ int max = MAX_CHARS_PER_LINE-8;
+
+ if (n < max)
+ {
+ return description;
+ }
+
+ StringBuilder builder = new StringBuilder();
+ StringBuilder line = new StringBuilder();
+ StringBuilder word = new StringBuilder();
+
+ for (int i = 0, offset=1; i < n; i += offset)
+ {
+ int codepoint = description.codePointAt(i);
+ offset = Character.charCount(codepoint);
+
+ if (codepoint == ' ')
+ {
+ if (line.length()+word.length()+1 >= max)
+ {
+ builder.append(line);
+ builder.append(String.format("%n"));
+ line = new StringBuilder();
+ line.append('\t');
+ }
+
+ line.append(word);
+ line.append(' ');
+ word = new StringBuilder();
+ }
+ else
+ {
+ word.appendCodePoint(codepoint);
+ }
+ }
+
+ if (line.length()+word.length()+1 >= max)
+ {
+ builder.append(line);
+ builder.append(String.format("%n"));
+ line = new StringBuilder();
+ line.append('\t');
+ }
+
+ line.append(word);
+ builder.append(line);
+
+ return builder.toString();
+ }
+
+ public String help()
+ {
+ String usage;
+
+ if (shortName == null)
+ {
+ usage = getUsage(longName);
+ }
+ else
+ {
+ usage = String.format("%s or %s", getUsage(shortName),
+ getUsage(longName));
+ }
+
+ int n = usage.length();
+
+ return String.format("%s%n\t%s.%n", usage, formatDescription());
+ }
+
+ public String doAction(int compatible) throws IllegalArgumentException
+ {
+ if (compatible < minCompatibility)
+ {
+ throw new IllegalArgumentException(String.format(
+ "'%s' option not available in compatibility mode %d",
+ invokedName, compatible));
+ }
+
+ return action();
+ }
+
+ protected abstract String action();
+
+ /**
+ * Make a copy of this object.
+ */
+ public final QueryAction copy()
+ {
+ try
+ {
+ ByteArrayOutputStream byteStr = new ByteArrayOutputStream();
+
+ new ObjectOutputStream(byteStr).writeObject(this);
+
+ QueryAction action = (QueryAction) new ObjectInputStream(
+ new ByteArrayInputStream(byteStr.toByteArray())).readObject();
+ action.same(this);
+
+ return action;
+ }
+ catch (Exception e)
+ {
+ throw new AssertionError(e);
+ }
+ }
+
+ private void same(QueryAction action)
+ {
+ longName = action.longName;
+ shortName = action.shortName;
+ invokedName = action.invokedName;
+ syntax = action.syntax;
+ optional = action.optional;
+ optionalProvided = action.optionalProvided;
+ required = action.required;
+ type = action.type;
+ description = action.description;
+ minCompatibility = action.minCompatibility;
+
+ if (action.optionalArgs != null)
+ {
+ optionalArgs = new String[action.optionalArgs.length];
+
+ for (int i = 0; i < action.optionalArgs.length; i++)
+ {
+ optionalArgs[i] = action.optionalArgs[i];
+ }
+ }
+
+ if (action.requiredArgs != null)
+ {
+ requiredArgs = new String[action.requiredArgs.length];
+
+ for (int i = 0; i < action.requiredArgs.length; i++)
+ {
+ requiredArgs[i] = action.requiredArgs[i];
+ }
+ }
+ }
+
+ public String getLongName()
+ {
+ return longName;
+ }
+
+ private String longName=null;
+ private String shortName=null;
+ private String invokedName=null;
+ private String syntax="";
+ private int optional=0;
+ private int optionalProvided=0;
+ private int required=0;
+ private String[] requiredArgs=null;
+ private String[] optionalArgs=null;
+ private QueryActionType type;
+ private String description;
+ private int minCompatibility=0;
+
+ private static final int MAX_CHARS_PER_LINE=80;
+}