Merge branch 'jsonsimple', fix #9

This commit is contained in:
yushijinhun 2018-04-15 10:22:10 +08:00
commit f460e0e230
No known key found for this signature in database
GPG key ID: 5BC167F73EA558E4
26 changed files with 2661 additions and 3129 deletions

View file

@ -10,6 +10,7 @@ import static org.to2mbn.authlibinjector.util.LoggingUtils.debug;
import static org.to2mbn.authlibinjector.util.LoggingUtils.info;
import static org.to2mbn.authlibinjector.util.LoggingUtils.isDebugOn;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.instrument.ClassFileTransformer;
import java.util.Base64;
import java.util.Optional;
@ -81,7 +82,7 @@ public final class AuthlibInjector {
YggdrasilConfiguration configuration;
try {
configuration = YggdrasilConfiguration.parse(apiRoot, metadataResponse);
} catch (IOException e) {
} catch (UncheckedIOException e) {
info("unable to parse metadata: {0}\n"
+ "metadata to parse:\n"
+ "{1}",

View file

@ -1,69 +1,59 @@
package org.to2mbn.authlibinjector;
import static java.text.MessageFormat.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static org.to2mbn.authlibinjector.util.KeyUtils.decodePublicKey;
import static org.to2mbn.authlibinjector.util.KeyUtils.loadX509PublicKey;
import java.io.IOException;
import java.security.GeneralSecurityException;
import static java.util.stream.Collectors.toList;
import static org.to2mbn.authlibinjector.util.JsonUtils.asArray;
import static org.to2mbn.authlibinjector.util.JsonUtils.asObject;
import static org.to2mbn.authlibinjector.util.JsonUtils.parseJson;
import java.io.UncheckedIOException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import org.to2mbn.authlibinjector.internal.org.json.JSONException;
import org.to2mbn.authlibinjector.internal.org.json.JSONObject;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject;
import org.to2mbn.authlibinjector.util.JsonUtils;
import org.to2mbn.authlibinjector.util.KeyUtils;
public class YggdrasilConfiguration {
public static YggdrasilConfiguration parse(String apiRoot, String metadataResponse) throws IOException {
public static YggdrasilConfiguration parse(String apiRoot, String metadataResponse) throws UncheckedIOException {
if (!apiRoot.endsWith("/")) apiRoot += "/";
try {
JSONObject response = new JSONObject(metadataResponse);
JSONObject response = asObject(parseJson(metadataResponse));
List<String> skinDomains = new ArrayList<>();
ofNullable(response.optJSONArray("skinDomains"))
.ifPresent(it -> it.forEach(domain -> {
if (domain instanceof String)
skinDomains.add((String) domain);
}));
List<String> skinDomains =
ofNullable(response.get("skinDomains"))
.map(it -> asArray(it).stream()
.map(JsonUtils::asString)
.collect(toList()))
.orElse(emptyList());
Optional<PublicKey> decodedPublickey;
String publickeyString = response.optString("signaturePublickey");
if (publickeyString == null) {
decodedPublickey = empty();
} else {
try {
decodedPublickey = of(loadX509PublicKey(decodePublicKey(publickeyString)));
} catch (IllegalArgumentException | GeneralSecurityException e) {
throw new IOException("Bad signature publickey", e);
}
}
Optional<PublicKey> decodedPublickey =
ofNullable(response.get("signaturePublickey"))
.map(JsonUtils::asString)
.map(KeyUtils::parseSignaturePublicKey);
Map<String, String> meta = new TreeMap<>();
ofNullable(response.optJSONObject("meta"))
.map(JSONObject::toMap)
.ifPresent(it -> it.forEach((k, v) -> meta.put(k, String.valueOf(v))));
Map<String, Object> meta =
ofNullable(response.get("meta"))
.map(it -> (Map<String, Object>) new TreeMap<>(asObject(it)))
.orElse(emptyMap());
return new YggdrasilConfiguration(apiRoot, unmodifiableList(skinDomains), unmodifiableMap(meta), decodedPublickey);
} catch (JSONException e) {
throw new IOException("Invalid json", e);
}
return new YggdrasilConfiguration(apiRoot, unmodifiableList(skinDomains), unmodifiableMap(meta), decodedPublickey);
}
private String apiRoot;
private List<String> skinDomains;
private Optional<PublicKey> decodedPublickey;
private Map<String, String> meta;
private Map<String, Object> meta;
public YggdrasilConfiguration(String apiRoot, List<String> skinDomains, Map<String, String> meta, Optional<PublicKey> decodedPublickey) {
public YggdrasilConfiguration(String apiRoot, List<String> skinDomains, Map<String, Object> meta, Optional<PublicKey> decodedPublickey) {
this.apiRoot = requireNonNull(apiRoot);
this.skinDomains = requireNonNull(skinDomains);
this.meta = requireNonNull(meta);
@ -78,7 +68,7 @@ public class YggdrasilConfiguration {
return skinDomains;
}
public Map<String, String> getMeta() {
public Map<String, Object> getMeta() {
return meta;
}

View file

@ -1,11 +1,18 @@
package org.to2mbn.authlibinjector.httpd;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singleton;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static org.to2mbn.authlibinjector.util.IOUtils.asString;
import static org.to2mbn.authlibinjector.util.IOUtils.getURL;
import static org.to2mbn.authlibinjector.util.IOUtils.newUncheckedIOException;
import static org.to2mbn.authlibinjector.util.IOUtils.postURL;
import static org.to2mbn.authlibinjector.util.JsonUtils.asArray;
import static org.to2mbn.authlibinjector.util.JsonUtils.asObject;
import static org.to2mbn.authlibinjector.util.JsonUtils.asString;
import static org.to2mbn.authlibinjector.util.JsonUtils.parseJson;
import static org.to2mbn.authlibinjector.util.LoggingUtils.debug;
import static org.to2mbn.authlibinjector.util.LoggingUtils.info;
import java.io.ByteArrayInputStream;
@ -16,9 +23,9 @@ import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.to2mbn.authlibinjector.YggdrasilConfiguration;
import org.to2mbn.authlibinjector.internal.org.json.JSONArray;
import org.to2mbn.authlibinjector.internal.org.json.JSONException;
import org.to2mbn.authlibinjector.internal.org.json.JSONObject;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONArray;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject;
import org.to2mbn.authlibinjector.util.JsonUtils;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response.Status;
@ -53,7 +60,7 @@ public class DeprecatedApiHttpd extends NanoHTTPD {
.flatMap(uuid -> queryCharacterProperty(uuid, "textures"))
.map(encoded -> asString(Base64.getDecoder().decode(encoded)))
.flatMap(texturesPayload -> obtainTextureUrl(texturesPayload, "SKIN"));
} catch (UncheckedIOException | JSONException e) {
} catch (UncheckedIOException e) {
info("[httpd] unable to fetch skin for {0}: {1}", username, e);
return of(newFixedLengthResponse(Status.INTERNAL_ERROR, null, null));
}
@ -77,29 +84,30 @@ public class DeprecatedApiHttpd extends NanoHTTPD {
}
}
private Optional<String> queryCharacterUUID(String username) throws UncheckedIOException, JSONException {
private Optional<String> queryCharacterUUID(String username) throws UncheckedIOException {
String responseText;
try {
responseText = asString(postURL(
configuration.getApiRoot() + "api/profiles/minecraft",
CONTENT_TYPE_JSON,
new JSONArray(new String[] { username })
.toString().getBytes(UTF_8)));
JSONArray.toJSONString(singleton(username)).getBytes(UTF_8)));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
debug("[httpd] query uuid of username {0}, response: {1}", username, responseText);
JSONArray response = new JSONArray(responseText);
if (response.length() == 0) {
JSONArray response = asArray(parseJson(responseText));
if (response.size() == 0) {
return empty();
} else if (response.length() == 1) {
return of(response.getJSONObject(0).getString("id"));
} else if (response.size() == 1) {
JSONObject profile = asObject(response.get(0));
return of(asString(profile.get("id")));
} else {
throw new JSONException("Unexpected response length");
throw newUncheckedIOException("Invalid JSON: Unexpected response length");
}
}
private Optional<String> queryCharacterProperty(String uuid, String property) throws UncheckedIOException, JSONException {
private Optional<String> queryCharacterProperty(String uuid, String propertyName) throws UncheckedIOException {
String responseText;
try {
responseText = asString(getURL(
@ -112,23 +120,24 @@ public class DeprecatedApiHttpd extends NanoHTTPD {
return empty();
}
debug("[httpd] query profile of {0}, response: {1}", uuid, responseText);
JSONObject response = new JSONObject(responseText);
for (Object element_ : response.getJSONArray("properties")) {
JSONObject element = (JSONObject) element_;
if (property.equals(element.getString("name"))) {
return of(element.getString("value"));
}
}
return empty();
JSONObject response = asObject(parseJson(responseText));
return asArray(response.get("properties")).stream()
.map(JsonUtils::asObject)
.filter(property -> asString(property.get("name")).equals(propertyName))
.findFirst()
.map(property -> asString(property.get("value")));
}
private Optional<String> obtainTextureUrl(String texturesPayload, String textureType) throws JSONException {
JSONObject textures = new JSONObject(texturesPayload).getJSONObject("textures");
if (textures.has(textureType)) {
return of(textures.getJSONObject(textureType).getString("url"));
} else {
return empty();
}
private Optional<String> obtainTextureUrl(String texturesPayload, String textureType) throws UncheckedIOException {
JSONObject payload = asObject(parseJson(texturesPayload));
JSONObject textures = asObject(payload.get("textures"));
return ofNullable(textures.get(textureType))
.map(JsonUtils::asObject)
.map(it -> ofNullable(it.get("url"))
.map(JsonUtils::asString)
.orElseThrow(() -> newUncheckedIOException("Invalid JSON: missing texture url")));
}
}

View file

@ -1,937 +0,0 @@
package org.to2mbn.authlibinjector.internal.org.json;
/*
* Copyright (c) 2002 JSON.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all
* copies or substantial portions of the Software.
*
* The Software shall be used for Good, not Evil.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* A JSONArray is an ordered sequence of values. Its external text form is a
* string wrapped in square brackets with commas separating the values. The
* internal form is an object having <code>get</code> and <code>opt</code>
* methods for accessing the values by index, and <code>put</code> methods for
* adding or replacing values. The values can be any of these types:
* <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
* <code>Number</code>, <code>String</code>, or the
* <code>JSONObject.NULL object</code>.
* <p>
* The constructor can convert a JSON text into a Java object. The
* <code>toString</code> method converts to JSON text.
* <p>
* A <code>get</code> method returns a value if one can be found, and throws an
* exception if one cannot be found. An <code>opt</code> method returns a
* default value instead of throwing an exception, and so is useful for
* obtaining optional values.
* <p>
* The generic <code>get()</code> and <code>opt()</code> methods return an
* object which you can cast or query for type. There are also typed
* <code>get</code> and <code>opt</code> methods that do type checking and type
* coercion for you.
* <p>
* The texts produced by the <code>toString</code> methods strictly conform to
* JSON syntax rules. The constructors are more forgiving in the texts they will
* accept:
* <ul>
* <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
* before the closing bracket.</li>
* <li>The <code>null</code> value will be inserted when there is <code>,</code>
* &nbsp;<small>(comma)</small> elision.</li>
* <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
* quote)</small>.</li>
* <li>Strings do not need to be quoted at all if they do not begin with a quote
* or single quote, and if they do not contain leading or trailing spaces, and
* if they do not contain any of these characters:
* <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and if
* they are not the reserved words <code>true</code>, <code>false</code>, or
* <code>null</code>.</li>
* </ul>
*
* @author JSON.org
* @version 2016-05-20
*/
public class JSONArray implements Iterable<Object>, Serializable {
private static final long serialVersionUID = 1L;
/**
* The arrayList where the JSONArray's properties are kept.
*/
private final List<Object> list;
/**
* Construct an empty JSONArray.
*/
public JSONArray() {
list = new ArrayList<>();
}
/**
* Construct a JSONArray from a JSONTokener.
*
* @param x
* A JSONTokener
* @throws JSONException
* If there is a syntax error.
*/
public JSONArray(JSONTokener x) throws JSONException {
this();
if (x.nextClean() != '[') {
throw x.syntaxError("A JSONArray text must start with '['");
}
if (x.nextClean() != ']') {
x.back();
for (;;) {
if (x.nextClean() == ',') {
x.back();
list.add(JSONObject.NULL);
} else {
x.back();
list.add(x.nextValue());
}
switch (x.nextClean()) {
case ',':
if (x.nextClean() == ']') {
return;
}
x.back();
break;
case ']':
return;
default:
throw x.syntaxError("Expected a ',' or ']'");
}
}
}
}
/**
* Construct a JSONArray from a source JSON text.
*
* @param source
* A string that begins with <code>[</code>&nbsp;<small>(left
* bracket)</small> and ends with <code>]</code> &nbsp;
* <small>(right bracket)</small>.
* @throws JSONException
* If there is a syntax error.
*/
public JSONArray(String source) throws JSONException {
this(new JSONTokener(source));
}
/**
* Construct a JSONArray from a Collection.
*
* @param collection
* A Collection.
*/
public JSONArray(Collection<?> collection) {
list = new ArrayList<>();
if (collection != null) {
for (Object o : collection) {
list.add(JSONObject.wrap(o));
}
}
}
/**
* Construct a JSONArray from an array
*
* @param array
* The array
* @throws JSONException
* If not an array.
*/
public <T> JSONArray(T[] array) throws JSONException {
this();
for (T element : array) {
this.put(JSONObject.wrap(element));
}
}
@Override
public Iterator<Object> iterator() {
return list.iterator();
}
/**
* Get the object value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return An object value.
* @throws JSONException
* If there is no value for the index.
*/
public Object get(int index) throws JSONException {
Object object = opt(index);
if (object == null) {
throw new JSONException("JSONArray[" + index + "] not found.");
}
return object;
}
/**
* Get the boolean value associated with an index. The string values "true"
* and "false" are converted to boolean.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The truth.
* @throws JSONException
* If there is no value for the index or if the value
* is not convertible to boolean.
*/
public boolean getBoolean(int index) throws JSONException {
Object object = get(index);
if (object.equals(Boolean.FALSE)
|| (object instanceof String && ((String) object)
.equalsIgnoreCase("false"))) {
return false;
} else if (object.equals(Boolean.TRUE)
|| (object instanceof String && ((String) object)
.equalsIgnoreCase("true"))) {
return true;
}
throw new JSONException("JSONArray[" + index + "] is not a boolean.");
}
/**
* Get the double value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The value.
* @throws JSONException
* If the key is not found or if the value cannot be
* converted to a number.
*/
public double getDouble(int index) throws JSONException {
Object object = get(index);
try {
return object instanceof Number ? ((Number) object).doubleValue()
: Double.parseDouble((String) object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index + "] is not a number.");
}
}
/**
* Get the enum value associated with an index.
*
* @param clazz
* The type of enum to retrieve.
* @param index
* The index must be between 0 and length() - 1.
* @param <E>
* The enum to retrieve
* @return The enum value at the index location
* @throws JSONException
* if the key is not found or if the value cannot be
* converted to an enum.
*/
public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONException {
E val = optEnum(clazz, index);
if (val == null) {
// JSONException should really take a throwable argument.
// If it did, I would re-implement this with the Enum.valueOf
// method and place any thrown exception in the JSONException
throw new JSONException("JSONObject[" + JSONObject.quote(Integer.toString(index))
+ "] is not an enum of type " + JSONObject.quote(clazz.getSimpleName())
+ ".");
}
return val;
}
/**
* Get the BigDecimal value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The value.
* @throws JSONException
* If the key is not found or if the value cannot be
* converted to a BigDecimal.
*/
public BigDecimal getBigDecimal(int index) throws JSONException {
Object object = get(index);
try {
return new BigDecimal(object.toString());
} catch (Exception e) {
throw new JSONException("JSONArray[" + index +
"] could not convert to BigDecimal.");
}
}
/**
* Get the BigInteger value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The value.
* @throws JSONException
* If the key is not found or if the value cannot be
* converted to a BigInteger.
*/
public BigInteger getBigInteger(int index) throws JSONException {
Object object = get(index);
try {
return new BigInteger(object.toString());
} catch (Exception e) {
throw new JSONException("JSONArray[" + index +
"] could not convert to BigInteger.");
}
}
/**
* Get the int value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The value.
* @throws JSONException
* If the key is not found or if the value is not a
* number.
*/
public int getInt(int index) throws JSONException {
Object object = get(index);
try {
return object instanceof Number ? ((Number) object).intValue()
: Integer.parseInt((String) object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index + "] is not a number.");
}
}
/**
* Get the JSONArray associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return A JSONArray value.
* @throws JSONException
* If there is no value for the index. or if the value
* is not a JSONArray
*/
public JSONArray getJSONArray(int index) throws JSONException {
Object object = get(index);
if (object instanceof JSONArray) {
return (JSONArray) object;
}
throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
}
/**
* Get the JSONObject associated with an index.
*
* @param index
* subscript
* @return A JSONObject value.
* @throws JSONException
* If there is no value for the index or if the value
* is not a JSONObject
*/
public JSONObject getJSONObject(int index) throws JSONException {
Object object = get(index);
if (object instanceof JSONObject) {
return (JSONObject) object;
}
throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
}
/**
* Get the long value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return The value.
* @throws JSONException
* If the key is not found or if the value cannot be
* converted to a number.
*/
public long getLong(int index) throws JSONException {
Object object = get(index);
try {
return object instanceof Number ? ((Number) object).longValue()
: Long.parseLong((String) object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index + "] is not a number.");
}
}
/**
* Get the string associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return A string value.
* @throws JSONException
* If there is no string value for the index.
*/
public String getString(int index) throws JSONException {
Object object = get(index);
if (object instanceof String) {
return (String) object;
}
throw new JSONException("JSONArray[" + index + "] not a string.");
}
/**
* Determine if the value is null.
*
* @param index
* The index must be between 0 and length() - 1.
* @return true if the value at the index is null, or if there is no value.
*/
public boolean isNull(int index) {
return JSONObject.NULL.equals(opt(index));
}
/**
* Get the number of elements in the JSONArray, included nulls.
*
* @return The length (or size).
*/
public int length() {
return list.size();
}
/**
* Get the optional object value associated with an index.
*
* @param index
* The index must be between 0 and length() - 1.
* @return An object value, or null if there is no object at that index.
*/
public Object opt(int index) {
return (index < 0 || index >= length()) ? null : list
.get(index);
}
/**
* Get the optional boolean value associated with an index. It returns the
* defaultValue if there is no value at that index or if it is not a Boolean
* or the String "true" or "false" (case insensitive).
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* A boolean default.
* @return The truth.
*/
public boolean optBoolean(int index, boolean defaultValue) {
try {
return getBoolean(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the optional double value associated with an index. The defaultValue
* is returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number.
*
* @param index
* subscript
* @param defaultValue
* The default value.
* @return The value.
*/
public double optDouble(int index, double defaultValue) {
try {
return getDouble(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the optional int value associated with an index. The defaultValue is
* returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number.
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default value.
* @return The value.
*/
public int optInt(int index, int defaultValue) {
try {
return getInt(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the enum value associated with a key.
*
* @param clazz
* The type of enum to retrieve.
* @param index
* The index must be between 0 and length() - 1.
* @param <E>
* The enum to retrieve
* @return The enum value at the index location or null if not found
*/
public <E extends Enum<E>> E optEnum(Class<E> clazz, int index) {
return this.optEnum(clazz, index, null);
}
/**
* Get the enum value associated with a key.
*
* @param clazz
* The type of enum to retrieve.
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default in case the value is not found
* @param <E>
* The enum to retrieve
* @return The enum value at the index location or defaultValue if the value
* is not found or cannot be assigned to clazz
*/
public <E extends Enum<E>> E optEnum(Class<E> clazz, int index, E defaultValue) {
try {
Object val = opt(index);
if (JSONObject.NULL.equals(val)) {
return defaultValue;
}
if (clazz.isAssignableFrom(val.getClass())) {
// we just checked it!
@SuppressWarnings("unchecked")
E myE = (E) val;
return myE;
}
return Enum.valueOf(clazz, val.toString());
} catch (IllegalArgumentException e) {
return defaultValue;
} catch (NullPointerException e) {
return defaultValue;
}
}
/**
* Get the optional BigInteger value associated with an index. The
* defaultValue is returned if there is no value for the index, or if the
* value is not a number and cannot be converted to a number.
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default value.
* @return The value.
*/
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
try {
return getBigInteger(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the optional BigDecimal value associated with an index. The
* defaultValue is returned if there is no value for the index, or if the
* value is not a number and cannot be converted to a number.
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default value.
* @return The value.
*/
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
try {
return getBigDecimal(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the optional JSONArray associated with an index.
*
* @param index
* subscript
* @return A JSONArray value, or null if the index has no value, or if the
* value is not a JSONArray.
*/
public JSONArray optJSONArray(int index) {
Object o = opt(index);
return o instanceof JSONArray ? (JSONArray) o : null;
}
/**
* Get the optional JSONObject associated with an index. Null is returned if
* the key is not found, or null if the index has no value, or if the value
* is not a JSONObject.
*
* @param index
* The index must be between 0 and length() - 1.
* @return A JSONObject value.
*/
public JSONObject optJSONObject(int index) {
Object o = opt(index);
return o instanceof JSONObject ? (JSONObject) o : null;
}
/**
* Get the optional long value associated with an index. The defaultValue is
* returned if there is no value for the index, or if the value is not a
* number and cannot be converted to a number.
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default value.
* @return The value.
*/
public long optLong(int index, long defaultValue) {
try {
return getLong(index);
} catch (Exception e) {
return defaultValue;
}
}
/**
* Get the optional string value associated with an index. It returns null if
* there is no value at that index. If the value is not a
* string and is not null, then it is coverted to a string.
*
* @param index
* The index must be between 0 and length() - 1.
* @return A String value.
*/
public String optString(int index) {
return this.optString(index, null);
}
/**
* Get the optional string associated with an index. The defaultValue is
* returned if the key is not found.
*
* @param index
* The index must be between 0 and length() - 1.
* @param defaultValue
* The default value.
* @return A String value.
*/
public String optString(int index, String defaultValue) {
Object object = opt(index);
return JSONObject.NULL.equals(object) ? defaultValue : object
.toString();
}
/**
* Put a value in the JSONArray, where the value will be a JSONArray which
* is produced from a Collection.
*
* @param value
* A Collection value.
* @return this.
*/
public JSONArray put(Collection<?> value) {
this.put(new JSONArray(value));
return this;
}
/**
* Put a value in the JSONArray, where the value will be a JSONObject which
* is produced from a Map.
*
* @param value
* A Map value.
* @return this.
*/
public JSONArray put(Map<?, ?> value) {
this.put(new JSONObject(value));
return this;
}
/**
* Append an object value. This increases the array's length by one.
*
* @param value
* An object value. The value should be a Boolean, Double,
* Integer, JSONArray, JSONObject, Long, or String, or the
* JSONObject.NULL object.
* @return this.
*/
public JSONArray put(Object value) {
list.add(value);
return this;
}
/**
* Put a value in the JSONArray, where the value will be a JSONArray which
* is produced from a Collection.
*
* @param index
* The subscript.
* @param value
* A Collection value.
* @return this.
* @throws JSONException
* If the index is negative or if the value is not
* finite.
*/
public JSONArray put(int index, Collection<?> value) throws JSONException {
this.put(index, new JSONArray(value));
return this;
}
/**
* Put a value in the JSONArray, where the value will be a JSONObject that
* is produced from a Map.
*
* @param index
* The subscript.
* @param value
* The Map value.
* @return this.
* @throws JSONException
* If the index is negative or if the the value is an
* invalid number.
*/
public JSONArray put(int index, Map<?, ?> value) throws JSONException {
this.put(index, new JSONObject(value));
return this;
}
/**
* Put or replace an object value in the JSONArray. If the index is greater
* than the length of the JSONArray, then null elements will be added as
* necessary to pad it out.
*
* @param index
* The subscript.
* @param value
* The value to put into the array. The value should be a
* Boolean, Double, Integer, JSONArray, JSONObject, Long, or
* String, or the JSONObject.NULL object.
* @return this.
* @throws JSONException
* If the index is negative or if the the value is an
* invalid number.
*/
public JSONArray put(int index, Object value) throws JSONException {
JSONObject.testValidity(value);
if (index < 0) {
throw new JSONException("JSONArray[" + index + "] not found.");
}
if (index < length()) {
list.set(index, value);
} else {
while (index != length()) {
this.put(JSONObject.NULL);
}
this.put(value);
}
return this;
}
/**
* Remove an index and close the hole.
*
* @param index
* The index of the element to be removed.
* @return The value that was associated with the index, or null if there
* was no value.
*/
public Object remove(int index) {
return index >= 0 && index < length()
? list.remove(index)
: null;
}
/**
* Make a JSON text of this JSONArray. For compactness, no unnecessary
* whitespace is added. If it is not possible to produce a syntactically
* correct JSON text then null will be returned instead. This could occur if
* the array contains an invalid number.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @return a printable, displayable, transmittable representation of the
* array.
*/
@Override
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
/**
* Make a prettyprinted JSON text of this JSONArray. Warning: This method
* assumes that the data structure is acyclical.
*
* @param indentFactor
* The number of spaces to add to each level of
* indentation.
* @return a printable, displayable, transmittable representation of the
* object, beginning with <code>[</code>&nbsp;<small>(left
* bracket)</small> and ending with <code>]</code> &nbsp;
* <small>(right bracket)</small>.
* @throws JSONException
* If the data structure is not acyclical
*/
public String toString(int indentFactor) throws JSONException {
StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0).toString();
}
}
/**
* Write the contents of the JSONArray as JSON text to a writer. For
* compactness, no whitespace is added.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer
* The writer
* @return The writer.
* @throws JSONException
* If the data structure is not acyclical or an I/O
* error occurs
*/
public Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
}
/**
* Write the contents of the JSONArray as JSON text to a writer. For
* compactness, no whitespace is added.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer
* Writes the serialized JSON
* @param indentFactor
* The number of spaces to add to each level of
* indentation.
* @param indent
* The indention of the top level.
* @return The writer.
* @throws JSONException
* If the data structure is not acyclical or an I/O
* error occurs
*/
public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException {
try {
boolean commanate = false;
int length = length();
writer.write('[');
if (length == 1) {
JSONObject.writeValue(writer, list.get(0),
indentFactor, indent);
} else if (length != 0) {
final int newindent = indent + indentFactor;
for (int i = 0; i < length; i += 1) {
if (commanate) {
writer.write(',');
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, newindent);
JSONObject.writeValue(writer, list.get(i),
indentFactor, newindent);
commanate = true;
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, indent);
}
writer.write(']');
return writer;
} catch (IOException e) {
throw new JSONException(e);
}
}
/**
* Returns a java.util.List containing all of the elements in this array. If
* an element in the array is a JSONArray or JSONObject it will also be
* converted.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @return a java.util.List containing the elements of this array
*/
public List<Object> toList() {
List<Object> results = new ArrayList<>(list.size());
for (Object element : list) {
if (element == null || JSONObject.NULL.equals(element)) {
results.add(null);
} else if (element instanceof JSONArray) {
results.add(((JSONArray) element).toList());
} else if (element instanceof JSONObject) {
results.add(((JSONObject) element).toMap());
} else {
results.add(element);
}
}
return results;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof JSONArray) {
JSONArray another = (JSONArray) obj;
return list.equals(another.list);
}
return false;
}
@Override
public int hashCode() {
return list.hashCode();
}
}

View file

@ -1,45 +0,0 @@
package org.to2mbn.authlibinjector.internal.org.json;
/**
* The JSONException is thrown by the JSON.org classes when things are amiss.
*
* @author JSON.org
* @version 2015-12-09
*/
public class JSONException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* Constructs a JSONException with an explanatory message.
*
* @param message
* Detail about the reason for the exception.
*/
public JSONException(final String message) {
super(message);
}
/**
* Constructs a JSONException with an explanatory message and cause.
*
* @param message
* Detail about the reason for the exception.
* @param cause
* The cause.
*/
public JSONException(final String message, final Throwable cause) {
super(message, cause);
}
/**
* Constructs a new JSONException with the specified cause.
*
* @param cause
* The cause.
*/
public JSONException(final Throwable cause) {
super(cause.getMessage(), cause);
}
}

View file

@ -1,487 +0,0 @@
package org.to2mbn.authlibinjector.internal.org.json;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
/*
* Copyright (c) 2002 JSON.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all
* copies or substantial portions of the Software.
*
* The Software shall be used for Good, not Evil.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* A JSONTokener takes a source string and extracts characters and tokens from
* it. It is used by the JSONObject and JSONArray constructors to parse JSON
* source strings.
*
* @author JSON.org
* @version 2014-05-03
*/
public class JSONTokener {
private long character;
private boolean eof;
private long index;
private long line;
private char previous;
private Reader reader;
private boolean usePrevious;
/**
* Construct a JSONTokener from a Reader.
*
* @param reader
* A reader.
*/
public JSONTokener(Reader reader) {
this.reader = reader.markSupported()
? reader
: new BufferedReader(reader);
eof = false;
usePrevious = false;
previous = 0;
index = 0;
character = 1;
line = 1;
}
/**
* Construct a JSONTokener from an InputStream.
*
* @param inputStream
* The source.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public JSONTokener(InputStream inputStream) throws JSONException {
this(new InputStreamReader(inputStream));
}
/**
* Construct a JSONTokener from a string.
*
* @param s
* A source string.
*/
public JSONTokener(String s) {
this(new StringReader(s));
}
/**
* Back up one character. This provides a sort of lookahead capability, so
* that you can test for a digit or letter before attempting to parse the
* next number or identifier.
*
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public void back() throws JSONException {
if (usePrevious || index <= 0) {
throw new JSONException("Stepping back two steps is not supported");
}
index -= 1;
character -= 1;
usePrevious = true;
eof = false;
}
/**
* Get the hex value of a character (base16).
*
* @param c
* A character between '0' and '9' or between 'A' and 'F' or
* between 'a' and 'f'.
* @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
public static int dehexchar(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - ('A' - 10);
}
if (c >= 'a' && c <= 'f') {
return c - ('a' - 10);
}
return -1;
}
public boolean end() {
return eof && !usePrevious;
}
/**
* Determine if the source string still contains characters that next() can
* consume.
*
* @return true if not yet at the end of the source.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public boolean more() throws JSONException {
this.next();
if (end()) {
return false;
}
back();
return true;
}
/**
* Get the next character in the source string.
*
* @return The next character, or 0 if past the end of the source string.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public char next() throws JSONException {
int c;
if (usePrevious) {
usePrevious = false;
c = previous;
} else {
try {
c = reader.read();
} catch (IOException exception) {
throw new JSONException(exception);
}
if (c <= 0) { // End of stream
eof = true;
c = 0;
}
}
index += 1;
if (previous == '\r') {
line += 1;
character = c == '\n' ? 0 : 1;
} else if (c == '\n') {
line += 1;
character = 0;
} else {
character += 1;
}
previous = (char) c;
return previous;
}
/**
* Consume the next character, and check that it matches a specified
* character.
*
* @param c
* The character to match.
* @return The character.
* @throws JSONException
* if the character does not match.
*/
public char next(char c) throws JSONException {
char n = this.next();
if (n != c) {
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
n + "'");
}
return n;
}
/**
* Get the next n characters.
*
* @param n
* The number of characters to take.
* @return A string of n characters.
* @throws JSONException
* Substring bounds error if there are not n
* characters remaining in the source string.
*/
public String next(int n) throws JSONException {
if (n == 0) {
return "";
}
char[] chars = new char[n];
int pos = 0;
while (pos < n) {
chars[pos] = this.next();
if (end()) {
throw this.syntaxError("Substring bounds error");
}
pos += 1;
}
return new String(chars);
}
/**
* Get the next char in the string, skipping whitespace.
*
* @throws JSONException
* If an I/O error or a syntax error occurs
* @return A character, or 0 if there are no more characters.
*/
public char nextClean() throws JSONException {
for (;;) {
char c = this.next();
if (c == 0 || c > ' ') {
return c;
}
}
}
/**
* Return the characters up to the next close quote character. Backslash
* processing is done. The formal JSON format does not allow strings in
* single quotes, but an implementation is allowed to accept them.
*
* @param quote
* The quoting character, either <code>"</code>&nbsp;
* <small>(double quote)</small> or <code>'</code>&nbsp;
* <small>(single quote)</small>.
* @return A String.
* @throws JSONException
* Unterminated string.
*/
public String nextString(char quote) throws JSONException {
char c;
StringBuilder sb = new StringBuilder();
for (;;) {
c = this.next();
switch (c) {
case 0:
case '\n':
case '\r':
throw this.syntaxError("Unterminated string");
case '\\':
c = this.next();
switch (c) {
case 'b':
sb.append('\b');
break;
case 't':
sb.append('\t');
break;
case 'n':
sb.append('\n');
break;
case 'f':
sb.append('\f');
break;
case 'r':
sb.append('\r');
break;
case 'u':
try {
sb.append((char) Integer.parseInt(this.next(4), 16));
} catch (NumberFormatException e) {
throw this.syntaxError("Illegal escape.", e);
}
break;
case '"':
case '\'':
case '\\':
case '/':
sb.append(c);
break;
default:
throw this.syntaxError("Illegal escape.");
}
break;
default:
if (c == quote) {
return sb.toString();
}
sb.append(c);
}
}
}
/**
* Get the text up but not including the specified character or the end of
* line, whichever comes first.
*
* @param delimiter
* A delimiter character.
* @return A string.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public String nextTo(char delimiter) throws JSONException {
StringBuilder sb = new StringBuilder();
for (;;) {
char c = this.next();
if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
if (c != 0) {
back();
}
return sb.toString().trim();
}
sb.append(c);
}
}
/**
* Get the text up but not including one of the specified delimiter
* characters or the end of line, whichever comes first.
*
* @param delimiters
* A set of delimiter characters.
* @return A string, trimmed.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public String nextTo(String delimiters) throws JSONException {
char c;
StringBuilder sb = new StringBuilder();
for (;;) {
c = this.next();
if (delimiters.indexOf(c) >= 0 || c == 0 ||
c == '\n' || c == '\r') {
if (c != 0) {
back();
}
return sb.toString().trim();
}
sb.append(c);
}
}
/**
* Get the next value. The value can be a Boolean, Double, Integer,
* JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
*
* @throws JSONException
* If syntax error.
* @return An object.
*/
public Object nextValue() throws JSONException {
char c = nextClean();
String string;
switch (c) {
case '"':
case '\'':
return nextString(c);
case '{':
back();
return new JSONObject(this);
case '[':
back();
return new JSONArray(this);
}
/*
* Handle unquoted text. This could be the values true, false, or
* null, or it can be a number. An implementation (such as this one)
* is allowed to also accept non-standard forms.
*
* Accumulate characters until we reach the end of the text or a
* formatting character.
*/
StringBuilder sb = new StringBuilder();
while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
sb.append(c);
c = this.next();
}
back();
string = sb.toString().trim();
if ("".equals(string)) {
throw this.syntaxError("Missing value");
}
return JSONObject.stringToValue(string);
}
/**
* Skip characters until the next character is the requested character. If
* the requested character is not found, no characters are skipped.
*
* @param to
* A character to skip to.
* @return The requested character, or zero if the requested character is
* not found.
* @throws JSONException
* If an I/O error or a syntax error occurs
*/
public char skipTo(char to) throws JSONException {
char c;
try {
long startIndex = index;
long startCharacter = character;
long startLine = line;
reader.mark(1000000);
do {
c = this.next();
if (c == 0) {
reader.reset();
index = startIndex;
character = startCharacter;
line = startLine;
return c;
}
} while (c != to);
} catch (IOException exception) {
throw new JSONException(exception);
}
back();
return c;
}
/**
* Make a JSONException to signal a syntax error.
*
* @param message
* The error message.
* @return A JSONException object, suitable for throwing
*/
public JSONException syntaxError(String message) {
return new JSONException(message + toString());
}
/**
* Make a JSONException to signal a syntax error.
*
* @param message
* The error message.
* @param causedBy
* The throwable that caused the error.
* @return A JSONException object, suitable for throwing
*/
public JSONException syntaxError(String message, Throwable causedBy) {
return new JSONException(message + toString(), causedBy);
}
/**
* Make a printable string of this JSONTokener.
*
* @return " at {index} [character {character} line {line}]"
*/
@Override
public String toString() {
return " at " + index + " [character " + character + " line " +
line + "]";
}
}

View file

@ -1,6 +0,0 @@
/**
* Modified <a href="https://github.com/stleary/JSON-java">org.json:json</a>.
* <p>
* See license in META-INF/licenses/org.json.txt
*/
package org.to2mbn.authlibinjector.internal.org.json;

View file

@ -0,0 +1,385 @@
/*
* $Id: JSONArray.java,v 1.1 2006/04/15 14:10:48 platform Exp $
* Created on 2006-4-10
*/
package org.to2mbn.authlibinjector.internal.org.json.simple;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* A JSON array. JSONObject supports java.util.List interface.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public class JSONArray extends ArrayList<Object> implements JSONAware, JSONStreamAware {
private static final long serialVersionUID = 3957988303675231981L;
/**
* Constructs an empty JSONArray.
*/
public JSONArray() {
super();
}
/**
* Constructs a JSONArray containing the elements of the specified
* collection, in the order they are returned by the collection's iterator.
*
* @param c
* the collection whose elements are to be placed into this JSONArray
*/
public JSONArray(Collection<?> c) {
super(c);
}
/**
* Encode a list into JSON text and write it to out.
* If this list is also a JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific behaviours will be ignored at this top level.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONValue#writeJSONString(Object, Writer)
*
* @param collection
* @param out
*/
public static void writeJSONString(Collection<?> collection, Writer out) throws IOException {
if (collection == null) {
out.write("null");
return;
}
boolean first = true;
Iterator<?> iter = collection.iterator();
out.write('[');
while (iter.hasNext()) {
if (first)
first = false;
else
out.write(',');
Object value = iter.next();
if (value == null) {
out.write("null");
continue;
}
JSONValue.writeJSONString(value, out);
}
out.write(']');
}
@Override
public void writeJSONString(Writer out) throws IOException {
writeJSONString(this, out);
}
/**
* Convert a list to JSON text. The result is a JSON array.
* If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONValue#toJSONString(Object)
*
* @param collection
* @return JSON text, or "null" if list is null.
*/
public static String toJSONString(Collection<?> collection) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(collection, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(byte[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(byte[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(short[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(short[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(int[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(int[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(long[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(long[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(float[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(float[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(double[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(double[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(boolean[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(boolean[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(char[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[\"");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write("\",\"");
out.write(String.valueOf(array[i]));
}
out.write("\"]");
}
}
public static String toJSONString(char[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(Object[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
JSONValue.writeJSONString(array[0], out);
for (int i = 1; i < array.length; i++) {
out.write(",");
JSONValue.writeJSONString(array[i], out);
}
out.write("]");
}
}
public static String toJSONString(Object[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
@Override
public String toJSONString() {
return toJSONString(this);
}
/**
* Returns a string representation of this array. This is equivalent to
* calling {@link JSONArray#toJSONString()}.
*/
@Override
public String toString() {
return toJSONString();
}
}

View file

@ -0,0 +1,13 @@
package org.to2mbn.authlibinjector.internal.org.json.simple;
/**
* Beans that support customized output of JSON text shall implement this interface.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public interface JSONAware {
/**
* @return JSON text
*/
String toJSONString();
}

View file

@ -0,0 +1,120 @@
/*
* $Id: JSONObject.java,v 1.1 2006/04/15 14:10:48 platform Exp $
* Created on 2006-4-10
*/
package org.to2mbn.authlibinjector.internal.org.json.simple;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public class JSONObject extends HashMap<String, Object> implements JSONAware, JSONStreamAware {
private static final long serialVersionUID = -503443796854799292L;
public JSONObject() {
super();
}
/**
* Allows creation of a JSONObject from a Map. After that, both the
* generated JSONObject and the Map can be modified independently.
*
* @param map
*/
public JSONObject(Map<String, ?> map) {
super(map);
}
/**
* Encode a map into JSON text and write it to out.
* If this map is also a JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific behaviours will be ignored at this top level.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONValue#writeJSONString(Object, Writer)
*
* @param map
* @param out
*/
public static void writeJSONString(Map<String, ?> map, Writer out) throws IOException {
if (map == null) {
out.write("null");
return;
}
boolean first = true;
Iterator<? extends Map.Entry<String, ?>> iter = map.entrySet().iterator();
out.write('{');
while (iter.hasNext()) {
if (first)
first = false;
else
out.write(',');
Map.Entry<String, ?> entry = iter.next();
out.write('\"');
out.write(JSONValue.escape(entry.getKey()));
out.write('\"');
out.write(':');
JSONValue.writeJSONString(entry.getValue(), out);
}
out.write('}');
}
@Override
public void writeJSONString(Writer out) throws IOException {
writeJSONString(this, out);
}
/**
* Convert a map to JSON text. The result is a JSON object.
* If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONValue#toJSONString(Object)
*
* @param map
* @return JSON text, or "null" if map is null.
*/
public static String toJSONString(Map<String, ?> map) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(map, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen with a StringWriter
throw new RuntimeException(e);
}
}
@Override
public String toJSONString() {
return toJSONString(this);
}
@Override
public String toString() {
return toJSONString();
}
public static String toString(String key, Object value) {
StringBuffer sb = new StringBuffer();
sb.append('\"');
if (key == null)
sb.append("null");
else
JSONValue.escape(key, sb);
sb.append('\"').append(':');
sb.append(JSONValue.toJSONString(value));
return sb.toString();
}
}

View file

@ -0,0 +1,16 @@
package org.to2mbn.authlibinjector.internal.org.json.simple;
import java.io.IOException;
import java.io.Writer;
/**
* Beans that support customized output of JSON text to a writer shall implement this interface.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public interface JSONStreamAware {
/**
* write JSON string to out.
*/
void writeJSONString(Writer out) throws IOException;
}

View file

@ -0,0 +1,259 @@
/*
* $Id: JSONValue.java,v 1.1 2006/04/15 14:37:04 platform Exp $
* Created on 2006-4-15
*/
package org.to2mbn.authlibinjector.internal.org.json.simple;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
// import java.util.List;
import java.util.Map;
import org.to2mbn.authlibinjector.internal.org.json.simple.parser.JSONParser;
import org.to2mbn.authlibinjector.internal.org.json.simple.parser.ParseException;
/**
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public class JSONValue {
/**
* Parse JSON text into java object from the input source.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.parser.JSONParser
*
* @param in
* @return Instance of the following:
* org.json.simple.JSONObject,
* org.json.simple.JSONArray,
* java.lang.String,
* java.lang.Number,
* java.lang.Boolean,
* null
*
* @throws IOException
* @throws ParseException
*/
public static Object parse(Reader in) throws IOException, ParseException {
return new JSONParser().parse(in);
}
public static Object parse(String s) throws ParseException {
return new JSONParser().parse(s);
}
/**
* Encode an object into JSON text and write it to out.
* <p>
* If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware will be considered firstly.
* <p>
* DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or List) with
* "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or JSONArray.writeJSONString(List, Writer) instead.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject#writeJSONString(Map, Writer)
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONArray#writeJSONString(List, Writer)
*
* @param value
* @param writer
*/
public static void writeJSONString(Object value, Writer out) throws IOException {
if (value == null) {
out.write("null");
return;
}
if (value instanceof String) {
out.write('\"');
out.write(escape((String) value));
out.write('\"');
return;
}
if (value instanceof Double) {
if (((Double) value).isInfinite() || ((Double) value).isNaN())
out.write("null");
else
out.write(value.toString());
return;
}
if (value instanceof Float) {
if (((Float) value).isInfinite() || ((Float) value).isNaN())
out.write("null");
else
out.write(value.toString());
return;
}
if (value instanceof Number) {
out.write(value.toString());
return;
}
if (value instanceof Boolean) {
out.write(value.toString());
return;
}
if ((value instanceof JSONStreamAware)) {
((JSONStreamAware) value).writeJSONString(out);
return;
}
if ((value instanceof JSONAware)) {
out.write(((JSONAware) value).toJSONString());
return;
}
if (value instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, ?> objectValue = (Map<String, ?>) value;
JSONObject.writeJSONString(objectValue, out);
return;
}
if (value instanceof Collection) {
JSONArray.writeJSONString((Collection<?>) value, out);
return;
}
if (value instanceof byte[]) {
JSONArray.writeJSONString((byte[]) value, out);
return;
}
if (value instanceof short[]) {
JSONArray.writeJSONString((short[]) value, out);
return;
}
if (value instanceof int[]) {
JSONArray.writeJSONString((int[]) value, out);
return;
}
if (value instanceof long[]) {
JSONArray.writeJSONString((long[]) value, out);
return;
}
if (value instanceof float[]) {
JSONArray.writeJSONString((float[]) value, out);
return;
}
if (value instanceof double[]) {
JSONArray.writeJSONString((double[]) value, out);
return;
}
if (value instanceof boolean[]) {
JSONArray.writeJSONString((boolean[]) value, out);
return;
}
if (value instanceof char[]) {
JSONArray.writeJSONString((char[]) value, out);
return;
}
if (value instanceof Object[]) {
JSONArray.writeJSONString((Object[]) value, out);
return;
}
out.write(value.toString());
}
/**
* Convert an object to JSON text.
* <p>
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
* <p>
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with
* "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject#toJSONString(Map)
* @see org.to2mbn.authlibinjector.internal.org.json.simple.JSONArray#toJSONString(List)
*
* @param value
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
*/
public static String toJSONString(Object value) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(value, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
/**
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
*
* @param s
* @return
*/
public static String escape(String s) {
if (s == null)
return null;
StringBuffer sb = new StringBuffer();
escape(s, sb);
return sb.toString();
}
/**
* @param s
* - Must not be null.
* @param sb
*/
static void escape(String s, StringBuffer sb) {
final int len = s.length();
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
switch (ch) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
case '/':
sb.append("\\/");
break;
default:
// Reference: http://www.unicode.org/versions/Unicode5.1.0/
if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) {
String ss = Integer.toHexString(ch);
sb.append("\\u");
for (int k = 0; k < 4 - ss.length(); k++) {
sb.append('0');
}
sb.append(ss.toUpperCase());
} else {
sb.append(ch);
}
}
} // for
}
}

View file

@ -0,0 +1,6 @@
/**
* Modified <a href="https://github.com/fangyidong/json-simple">json-simple</a>.
* <p>
* See license in META-INF/licenses/json-simple.txt
*/
package org.to2mbn.authlibinjector.internal.org.json.simple;

View file

@ -0,0 +1,23 @@
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
import java.util.List;
import java.util.Map;
/**
* Container factory for creating containers for JSON object and JSON array.
*
* @see org.to2mbn.authlibinjector.internal.org.json.simple.parser.JSONParser#parse(java.io.Reader, ContainerFactory)
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public interface ContainerFactory {
/**
* @return A Map instance to store JSON object, or null if you want to use org.json.simple.JSONObject.
*/
Map<String, Object> createObjectContainer();
/**
* @return A List instance to store JSON array, or null if you want to use org.json.simple.JSONArray.
*/
List<Object> creatArrayContainer();
}

View file

@ -0,0 +1,112 @@
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
import java.io.IOException;
/**
* A simplified and stoppable SAX-like content handler for stream processing of JSON text.
*
* @see org.xml.sax.ContentHandler
* @see org.to2mbn.authlibinjector.internal.org.json.simple.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean)
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public interface ContentHandler {
/**
* Receive notification of the beginning of JSON processing.
* The parser will invoke this method only once.
*
* @throws ParseException
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
*/
void startJSON() throws ParseException, IOException;
/**
* Receive notification of the end of JSON processing.
*
* @throws ParseException
*/
void endJSON() throws ParseException, IOException;
/**
* Receive notification of the beginning of a JSON object.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
* @see #endJSON
*/
boolean startObject() throws ParseException, IOException;
/**
* Receive notification of the end of a JSON object.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*
* @see #startObject
*/
boolean endObject() throws ParseException, IOException;
/**
* Receive notification of the beginning of a JSON object entry.
*
* @param key
* - Key of a JSON object entry.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*
* @see #endObjectEntry
*/
boolean startObjectEntry(String key) throws ParseException, IOException;
/**
* Receive notification of the end of the value of previous object entry.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*
* @see #startObjectEntry
*/
boolean endObjectEntry() throws ParseException, IOException;
/**
* Receive notification of the beginning of a JSON array.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*
* @see #endArray
*/
boolean startArray() throws ParseException, IOException;
/**
* Receive notification of the end of a JSON array.
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*
* @see #startArray
*/
boolean endArray() throws ParseException, IOException;
/**
* Receive notification of the JSON primitive values:
* java.lang.String,
* java.lang.Number,
* java.lang.Boolean
* null
*
* @param value
* - Instance of the following:
* java.lang.String,
* java.lang.Number,
* java.lang.Boolean
* null
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
*/
boolean primitive(Object value) throws ParseException, IOException;
}

View file

@ -0,0 +1,533 @@
/*
* $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $
* Created on 2006-4-15
*/
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONArray;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject;
/**
* Parser for JSON text. Please note that JSONParser is NOT thread-safe.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
public class JSONParser {
public static final int S_INIT = 0;
public static final int S_IN_FINISHED_VALUE = 1;// string,number,boolean,null,object,array
public static final int S_IN_OBJECT = 2;
public static final int S_IN_ARRAY = 3;
public static final int S_PASSED_PAIR_KEY = 4;
public static final int S_IN_PAIR_VALUE = 5;
public static final int S_END = 6;
public static final int S_IN_ERROR = -1;
private LinkedList<Integer> handlerStatusStack;
private Yylex lexer = new Yylex((Reader) null);
private Yytoken token = null;
private int status = S_INIT;
private int peekStatus(LinkedList<Integer> statusStack) {
if (statusStack.size() == 0)
return -1;
Integer status = statusStack.getFirst();
return status.intValue();
}
/**
* Reset the parser to the initial state without resetting the underlying reader.
*
*/
public void reset() {
token = null;
status = S_INIT;
handlerStatusStack = null;
}
/**
* Reset the parser to the initial state with a new character reader.
*
* @param in
* - The new character reader.
* @throws IOException
* @throws ParseException
*/
public void reset(Reader in) {
lexer.yyreset(in);
reset();
}
/**
* @return The position of the beginning of the current token.
*/
public int getPosition() {
return lexer.getPosition();
}
public Object parse(String s) throws ParseException {
return parse(s, (ContainerFactory) null);
}
public Object parse(String s, ContainerFactory containerFactory) throws ParseException {
StringReader in = new StringReader(s);
try {
return parse(in, containerFactory);
} catch (IOException ie) {
/*
* Actually it will never happen.
*/
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
}
}
public Object parse(Reader in) throws IOException, ParseException {
return parse(in, (ContainerFactory) null);
}
/**
* Parse JSON text into java object from the input source.
*
* @param in
* @param containerFactory
* - Use this factory to createyour own JSON object and JSON array containers.
* @return Instance of the following:
* org.json.simple.JSONObject,
* org.json.simple.JSONArray,
* java.lang.String,
* java.lang.Number,
* java.lang.Boolean,
* null
*
* @throws IOException
* @throws ParseException
*/
public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException {
reset(in);
LinkedList<Integer> statusStack = new LinkedList<>();
LinkedList<Object> valueStack = new LinkedList<>();
try {
do {
nextToken();
switch (status) {
case S_INIT: {
switch (token.type) {
case Yytoken.TYPE_VALUE: {
status = S_IN_FINISHED_VALUE;
statusStack.addFirst(status);
valueStack.addFirst(token.value);
break;
}
case Yytoken.TYPE_LEFT_BRACE: {
status = S_IN_OBJECT;
statusStack.addFirst(status);
valueStack.addFirst(createObjectContainer(containerFactory));
break;
}
case Yytoken.TYPE_LEFT_SQUARE: {
status = S_IN_ARRAY;
statusStack.addFirst(status);
valueStack.addFirst(createArrayContainer(containerFactory));
break;
}
default:
status = S_IN_ERROR;
}// inner switch
break;
}
case S_IN_FINISHED_VALUE: {
if (token.type == Yytoken.TYPE_EOF)
return valueStack.removeFirst();
else
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
case S_IN_OBJECT: {
switch (token.type) {
case Yytoken.TYPE_COMMA:
break;
case Yytoken.TYPE_VALUE: {
if (token.value instanceof String) {
String key = (String) token.value;
valueStack.addFirst(key);
status = S_PASSED_PAIR_KEY;
statusStack.addFirst(status);
} else {
status = S_IN_ERROR;
}
break;
}
case Yytoken.TYPE_RIGHT_BRACE: {
if (valueStack.size() > 1) {
statusStack.removeFirst();
valueStack.removeFirst();
status = peekStatus(statusStack);
} else {
status = S_IN_FINISHED_VALUE;
}
break;
}
default:
status = S_IN_ERROR;
break;
}// inner switch
break;
}
case S_PASSED_PAIR_KEY: {
switch (token.type) {
case Yytoken.TYPE_COLON:
break;
case Yytoken.TYPE_VALUE: {
statusStack.removeFirst();
String key = (String) valueStack.removeFirst();
@SuppressWarnings("unchecked")
Map<String, Object> parent = (Map<String, Object>) valueStack.getFirst();
parent.put(key, token.value);
status = peekStatus(statusStack);
break;
}
case Yytoken.TYPE_LEFT_SQUARE: {
statusStack.removeFirst();
String key = (String) valueStack.removeFirst();
@SuppressWarnings("unchecked")
Map<String, Object> parent = (Map<String, Object>) valueStack.getFirst();
List<Object> newArray = createArrayContainer(containerFactory);
parent.put(key, newArray);
status = S_IN_ARRAY;
statusStack.addFirst(status);
valueStack.addFirst(newArray);
break;
}
case Yytoken.TYPE_LEFT_BRACE: {
statusStack.removeFirst();
String key = (String) valueStack.removeFirst();
@SuppressWarnings("unchecked")
Map<String, Object> parent = (Map<String, Object>) valueStack.getFirst();
Map<String, Object> newObject = createObjectContainer(containerFactory);
parent.put(key, newObject);
status = S_IN_OBJECT;
statusStack.addFirst(status);
valueStack.addFirst(newObject);
break;
}
default:
status = S_IN_ERROR;
}
break;
}
case S_IN_ARRAY: {
switch (token.type) {
case Yytoken.TYPE_COMMA:
break;
case Yytoken.TYPE_VALUE: {
@SuppressWarnings("unchecked")
List<Object> val = (List<Object>) valueStack.getFirst();
val.add(token.value);
break;
}
case Yytoken.TYPE_RIGHT_SQUARE: {
if (valueStack.size() > 1) {
statusStack.removeFirst();
valueStack.removeFirst();
status = peekStatus(statusStack);
} else {
status = S_IN_FINISHED_VALUE;
}
break;
}
case Yytoken.TYPE_LEFT_BRACE: {
@SuppressWarnings("unchecked")
List<Object> val = (List<Object>) valueStack.getFirst();
Map<String, Object> newObject = createObjectContainer(containerFactory);
val.add(newObject);
status = S_IN_OBJECT;
statusStack.addFirst(status);
valueStack.addFirst(newObject);
break;
}
case Yytoken.TYPE_LEFT_SQUARE: {
@SuppressWarnings("unchecked")
List<Object> val = (List<Object>) valueStack.getFirst();
List<Object> newArray = createArrayContainer(containerFactory);
val.add(newArray);
status = S_IN_ARRAY;
statusStack.addFirst(status);
valueStack.addFirst(newArray);
break;
}
default:
status = S_IN_ERROR;
}// inner switch
break;
}
case S_IN_ERROR:
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}// switch
if (status == S_IN_ERROR) {
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
} while (token.type != Yytoken.TYPE_EOF);
} catch (IOException ie) {
throw ie;
}
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
private void nextToken() throws ParseException, IOException {
token = lexer.yylex();
if (token == null)
token = new Yytoken(Yytoken.TYPE_EOF, null);
}
private Map<String, Object> createObjectContainer(ContainerFactory containerFactory) {
if (containerFactory == null)
return new JSONObject();
Map<String, Object> m = containerFactory.createObjectContainer();
if (m == null)
return new JSONObject();
return m;
}
private List<Object> createArrayContainer(ContainerFactory containerFactory) {
if (containerFactory == null)
return new JSONArray();
List<Object> l = containerFactory.creatArrayContainer();
if (l == null)
return new JSONArray();
return l;
}
public void parse(String s, ContentHandler contentHandler) throws ParseException {
parse(s, contentHandler, false);
}
public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException {
StringReader in = new StringReader(s);
try {
parse(in, contentHandler, isResume);
} catch (IOException ie) {
/*
* Actually it will never happen.
*/
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
}
}
public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException {
parse(in, contentHandler, false);
}
/**
* Stream processing of JSON text.
*
* @see ContentHandler
*
* @param in
* @param contentHandler
* @param isResume
* - Indicates if it continues previous parsing operation.
* If set to true, resume parsing the old stream, and parameter 'in' will be ignored.
* If this method is called for the first time in this instance, isResume will be ignored.
*
* @throws IOException
* @throws ParseException
*/
public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException {
if (!isResume) {
reset(in);
handlerStatusStack = new LinkedList<>();
} else {
if (handlerStatusStack == null) {
isResume = false;
reset(in);
handlerStatusStack = new LinkedList<>();
}
}
LinkedList<Integer> statusStack = handlerStatusStack;
try {
do {
switch (status) {
case S_INIT:
contentHandler.startJSON();
nextToken();
switch (token.type) {
case Yytoken.TYPE_VALUE:
status = S_IN_FINISHED_VALUE;
statusStack.addFirst(status);
if (!contentHandler.primitive(token.value))
return;
break;
case Yytoken.TYPE_LEFT_BRACE:
status = S_IN_OBJECT;
statusStack.addFirst(status);
if (!contentHandler.startObject())
return;
break;
case Yytoken.TYPE_LEFT_SQUARE:
status = S_IN_ARRAY;
statusStack.addFirst(status);
if (!contentHandler.startArray())
return;
break;
default:
status = S_IN_ERROR;
}// inner switch
break;
case S_IN_FINISHED_VALUE:
nextToken();
if (token.type == Yytoken.TYPE_EOF) {
contentHandler.endJSON();
status = S_END;
return;
} else {
status = S_IN_ERROR;
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
case S_IN_OBJECT:
nextToken();
switch (token.type) {
case Yytoken.TYPE_COMMA:
break;
case Yytoken.TYPE_VALUE:
if (token.value instanceof String) {
String key = (String) token.value;
status = S_PASSED_PAIR_KEY;
statusStack.addFirst(status);
if (!contentHandler.startObjectEntry(key))
return;
} else {
status = S_IN_ERROR;
}
break;
case Yytoken.TYPE_RIGHT_BRACE:
if (statusStack.size() > 1) {
statusStack.removeFirst();
status = peekStatus(statusStack);
} else {
status = S_IN_FINISHED_VALUE;
}
if (!contentHandler.endObject())
return;
break;
default:
status = S_IN_ERROR;
break;
}// inner switch
break;
case S_PASSED_PAIR_KEY:
nextToken();
switch (token.type) {
case Yytoken.TYPE_COLON:
break;
case Yytoken.TYPE_VALUE:
statusStack.removeFirst();
status = peekStatus(statusStack);
if (!contentHandler.primitive(token.value))
return;
if (!contentHandler.endObjectEntry())
return;
break;
case Yytoken.TYPE_LEFT_SQUARE:
statusStack.removeFirst();
statusStack.addFirst(S_IN_PAIR_VALUE);
status = S_IN_ARRAY;
statusStack.addFirst(status);
if (!contentHandler.startArray())
return;
break;
case Yytoken.TYPE_LEFT_BRACE:
statusStack.removeFirst();
statusStack.addFirst(S_IN_PAIR_VALUE);
status = S_IN_OBJECT;
statusStack.addFirst(status);
if (!contentHandler.startObject())
return;
break;
default:
status = S_IN_ERROR;
}
break;
case S_IN_PAIR_VALUE:
/*
* S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
* therefore delay consuming token until next round.
*/
statusStack.removeFirst();
status = peekStatus(statusStack);
if (!contentHandler.endObjectEntry())
return;
break;
case S_IN_ARRAY:
nextToken();
switch (token.type) {
case Yytoken.TYPE_COMMA:
break;
case Yytoken.TYPE_VALUE:
if (!contentHandler.primitive(token.value))
return;
break;
case Yytoken.TYPE_RIGHT_SQUARE:
if (statusStack.size() > 1) {
statusStack.removeFirst();
status = peekStatus(statusStack);
} else {
status = S_IN_FINISHED_VALUE;
}
if (!contentHandler.endArray())
return;
break;
case Yytoken.TYPE_LEFT_BRACE:
status = S_IN_OBJECT;
statusStack.addFirst(status);
if (!contentHandler.startObject())
return;
break;
case Yytoken.TYPE_LEFT_SQUARE:
status = S_IN_ARRAY;
statusStack.addFirst(status);
if (!contentHandler.startArray())
return;
break;
default:
status = S_IN_ERROR;
}// inner switch
break;
case S_END:
return;
case S_IN_ERROR:
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}// switch
if (status == S_IN_ERROR) {
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
} while (token.type != Yytoken.TYPE_EOF);
} catch (IOException | ParseException e) {
status = S_IN_ERROR;
throw e;
}
status = S_IN_ERROR;
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
}
}

View file

@ -0,0 +1,91 @@
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
/**
* ParseException explains why and where the error occurs in source JSON text.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*
*/
public class ParseException extends Exception {
private static final long serialVersionUID = -7880698968187728547L;
public static final int ERROR_UNEXPECTED_CHAR = 0;
public static final int ERROR_UNEXPECTED_TOKEN = 1;
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
private int errorType;
private Object unexpectedObject;
private int position;
public ParseException(int errorType) {
this(-1, errorType, null);
}
public ParseException(int errorType, Object unexpectedObject) {
this(-1, errorType, unexpectedObject);
}
public ParseException(int position, int errorType, Object unexpectedObject) {
this.position = position;
this.errorType = errorType;
this.unexpectedObject = unexpectedObject;
}
public int getErrorType() {
return errorType;
}
public void setErrorType(int errorType) {
this.errorType = errorType;
}
/**
* @see org.to2mbn.authlibinjector.internal.org.json.simple.parser.JSONParser#getPosition()
*
* @return The character position (starting with 0) of the input where the error occurs.
*/
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
/**
* @see org.to2mbn.authlibinjector.internal.org.json.simple.parser.Yytoken
*
* @return One of the following base on the value of errorType:
* ERROR_UNEXPECTED_CHAR java.lang.Character
* ERROR_UNEXPECTED_TOKEN org.json.simple.parser.Yytoken
* ERROR_UNEXPECTED_EXCEPTION java.lang.Exception
*/
public Object getUnexpectedObject() {
return unexpectedObject;
}
public void setUnexpectedObject(Object unexpectedObject) {
this.unexpectedObject = unexpectedObject;
}
@Override
public String getMessage() {
StringBuffer sb = new StringBuffer();
switch (errorType) {
case ERROR_UNEXPECTED_CHAR:
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append(".");
break;
case ERROR_UNEXPECTED_TOKEN:
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(".");
break;
case ERROR_UNEXPECTED_EXCEPTION:
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
break;
default:
sb.append("Unkown error at position ").append(position).append(".");
break;
}
return sb.toString();
}
}

View file

@ -0,0 +1,705 @@
/* The following code was generated by JFlex 1.4.2 */
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
class Yylex {
/** This character denotes the end of file */
public static final int YYEOF = -1;
/** initial size of the lookahead buffer */
private static final int ZZ_BUFFERSIZE = 16384;
/** lexical states */
public static final int YYINITIAL = 0;
public static final int STRING_BEGIN = 2;
/**
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
* at the beginning of a line
* l is of the form l = 2*k, k a non negative integer
*/
private static final int ZZ_LEXSTATE[] = {
0, 0, 1, 1
};
/**
* Translates characters to character classes
*/
private static final String ZZ_CMAP_PACKED =
"\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" +
"\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5" +
"\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21" +
"\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20" +
"\5\0\1\25\1\0\1\26\uff82\0";
/**
* Translates characters to character classes
*/
private static final char[] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
/**
* Translates DFA states to action switch labels.
*/
private static final int[] ZZ_ACTION = zzUnpackAction();
private static final String ZZ_ACTION_PACKED_0 =
"\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" +
"\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0" +
"\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24" +
"\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0" +
"\1\30";
private static int[] zzUnpackAction() {
int[] result = new int[45];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAction(String packed, int offset, int[] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do
result[j++] = value;
while (--count > 0);
}
return j;
}
/**
* Translates a state to a row index in the transition table
*/
private static final int[] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 =
"\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" +
"\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66" +
"\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195" +
"\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66" +
"\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252" +
"\0\66\0\66\0\u026d\0\u0288\0\66";
private static int[] zzUnpackRowMap() {
int[] result = new int[45];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
}
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int high = packed.charAt(i++) << 16;
result[j++] = high | packed.charAt(i++);
}
return j;
}
/**
* The transition table of the DFA
*/
private static final int ZZ_TRANS[] = {
2, 2, 3, 4, 2, 2, 2, 5, 2, 6,
2, 2, 7, 8, 2, 9, 2, 2, 2, 2,
2, 10, 11, 12, 13, 14, 15, 16, 16, 16,
16, 16, 16, 16, 16, 17, 18, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 4, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 4, 19, 20, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 20, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 5, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
21, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
23, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 16, 16, 16, 16, 16, 16, 16,
16, -1, -1, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-1, -1, -1, -1, -1, -1, -1, -1, 24, 25,
26, 27, 28, 29, 30, 31, 32, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 34, 35, -1, -1,
34, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 37, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 38, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 39, -1, 39, -1, 39, -1, -1,
-1, -1, -1, 39, 39, -1, -1, -1, -1, 39,
39, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 33, -1, 20, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 20, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 35,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 38, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 40,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 41, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 42, -1, 42, -1, 42,
-1, -1, -1, -1, -1, 42, 42, -1, -1, -1,
-1, 42, 42, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 43, -1, 43, -1, 43, -1, -1, -1,
-1, -1, 43, 43, -1, -1, -1, -1, 43, 43,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 44,
-1, 44, -1, 44, -1, -1, -1, -1, -1, 44,
44, -1, -1, -1, -1, 44, 44, -1, -1, -1,
-1, -1, -1, -1, -1,
};
/* error codes */
private static final int ZZ_UNKNOWN_ERROR = 0;
private static final int ZZ_NO_MATCH = 1;
private static final int ZZ_PUSHBACK_2BIG = 2;
/* error messages for the codes above */
private static final String ZZ_ERROR_MSG[] = {
"Unkown internal scanner error",
"Error: could not match input",
"Error: pushback value was too large"
};
/**
* ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
*/
private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute();
private static final String ZZ_ATTRIBUTE_PACKED_0 =
"\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" +
"\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" +
"\2\0\1\11";
private static int[] zzUnpackAttribute() {
int[] result = new int[45];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do
result[j++] = value;
while (--count > 0);
}
return j;
}
/** the input device */
private Reader zzReader;
/** the current state of the DFA */
private int zzState;
/** the current lexical state */
private int zzLexicalState = YYINITIAL;
/**
* this buffer contains the current text to be matched and is
* the source of the yytext() string
*/
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
/** the textposition at the last accepting state */
private int zzMarkedPos;
/** the current text position in the buffer */
private int zzCurrentPos;
/** startRead marks the beginning of the yytext() string in the buffer */
private int zzStartRead;
/**
* endRead marks the last character in the buffer, that has been read
* from input
*/
private int zzEndRead;
/** the number of characters up to the start of the matched text */
private int yychar;
/** zzAtEOF == true <=> the scanner is at the EOF */
private boolean zzAtEOF;
/* user code: */
private StringBuffer sb = new StringBuffer();
int getPosition() {
return yychar;
}
/**
* Creates a new scanner
* There is also a InputStream version of this constructor.
*
* @param in
* the Reader to read input from.
*/
Yylex(Reader in) {
zzReader = in;
}
/**
* Creates a new scanner.
* There is also Reader version of this constructor.
*
* @param in
* the Inputstream to read input from.
*/
Yylex(InputStream in) {
this(new InputStreamReader(in));
}
/**
* Unpacks the compressed character translation table.
*
* @param packed
* the packed character translation table
* @return the unpacked character translation table
*/
private static char[] zzUnpackCMap(String packed) {
char[] map = new char[0x10000];
int i = 0; /* index in packed string */
int j = 0; /* index in unpacked array */
while (i < 90) {
int count = packed.charAt(i++);
char value = packed.charAt(i++);
do
map[j++] = value;
while (--count > 0);
}
return map;
}
/**
* Refills the input buffer.
*
* @return <code>false</code>, iff there was new input.
*
* @exception IOException
* if any I/O-Error occurs
*/
private boolean zzRefill() throws IOException {
/* first: make room (if you can) */
if (zzStartRead > 0) {
System.arraycopy(zzBuffer, zzStartRead,
zzBuffer, 0,
zzEndRead - zzStartRead);
/* translate stored positions */
zzEndRead -= zzStartRead;
zzCurrentPos -= zzStartRead;
zzMarkedPos -= zzStartRead;
zzStartRead = 0;
}
/* is the buffer big enough? */
if (zzCurrentPos >= zzBuffer.length) {
/* if not: blow it up */
char newBuffer[] = new char[zzCurrentPos * 2];
System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
zzBuffer = newBuffer;
}
/* finally: fill the buffer with new input */
int numRead = zzReader.read(zzBuffer, zzEndRead,
zzBuffer.length - zzEndRead);
if (numRead > 0) {
zzEndRead += numRead;
return false;
}
// unlikely but not impossible: read 0 characters, but not at end of stream
if (numRead == 0) {
int c = zzReader.read();
if (c == -1) {
return true;
} else {
zzBuffer[zzEndRead++] = (char) c;
return false;
}
}
// numRead < 0
return true;
}
/**
* Closes the input stream.
*/
public final void yyclose() throws IOException {
zzAtEOF = true; /* indicate end of file */
zzEndRead = zzStartRead; /* invalidate buffer */
if (zzReader != null)
zzReader.close();
}
/**
* Resets the scanner to read from a new input stream.
* Does not close the old reader.
*
* All internal variables are reset, the old input stream
* <b>cannot</b> be reused (internal buffer is discarded and lost).
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
*
* @param reader
* the new input stream
*/
public final void yyreset(Reader reader) {
zzReader = reader;
zzAtEOF = false;
zzEndRead = zzStartRead = 0;
zzCurrentPos = zzMarkedPos = 0;
yychar = 0;
zzLexicalState = YYINITIAL;
}
/**
* Returns the current lexical state.
*/
public final int yystate() {
return zzLexicalState;
}
/**
* Enters a new lexical state
*
* @param newState
* the new lexical state
*/
public final void yybegin(int newState) {
zzLexicalState = newState;
}
/**
* Returns the text matched by the current regular expression.
*/
public final String yytext() {
return new String(zzBuffer, zzStartRead, zzMarkedPos - zzStartRead);
}
/**
* Returns the character at position <tt>pos</tt> from the
* matched text.
*
* It is equivalent to yytext().charAt(pos), but faster
*
* @param pos
* the position of the character to fetch.
* A value from 0 to yylength()-1.
*
* @return the character at position pos
*/
public final char yycharat(int pos) {
return zzBuffer[zzStartRead + pos];
}
/**
* Returns the length of the matched text region.
*/
public final int yylength() {
return zzMarkedPos - zzStartRead;
}
/**
* Reports an error that occured while scanning.
*
* In a wellformed scanner (no or only correct usage of
* yypushback(int) and a match-all fallback rule) this method
* will only be called with things that "Can't Possibly Happen".
* If this method is called, something is seriously wrong
* (e.g. a JFlex bug producing a faulty scanner etc.).
*
* Usual syntax/scanner level error handling should be done
* in error fallback rules.
*
* @param errorCode
* the code of the errormessage to display
*/
private void zzScanError(int errorCode) {
String message;
try {
message = ZZ_ERROR_MSG[errorCode];
} catch (ArrayIndexOutOfBoundsException e) {
message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
}
throw new IllegalStateException(message);
}
/**
* Pushes the specified amount of characters back into the input stream.
*
* They will be read again by then next call of the scanning method
*
* @param number
* the number of characters to be read again.
* This number must not be greater than yylength()!
*/
public void yypushback(int number) {
if (number > yylength())
zzScanError(ZZ_PUSHBACK_2BIG);
zzMarkedPos -= number;
}
/**
* Resumes scanning until the next regular expression is matched,
* the end of input is encountered or an I/O-Error occurs.
*
* @return the next token
* @exception IOException
* if any I/O-Error occurs
*/
public Yytoken yylex() throws IOException, ParseException {
int zzInput;
int zzAction;
// cached fields:
int zzCurrentPosL;
int zzMarkedPosL;
int zzEndReadL = zzEndRead;
char[] zzBufferL = zzBuffer;
char[] zzCMapL = ZZ_CMAP;
int[] zzTransL = ZZ_TRANS;
int[] zzRowMapL = ZZ_ROWMAP;
int[] zzAttrL = ZZ_ATTRIBUTE;
while (true) {
zzMarkedPosL = zzMarkedPos;
yychar += zzMarkedPosL - zzStartRead;
zzAction = -1;
zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
zzState = ZZ_LEXSTATE[zzLexicalState];
zzForAction: {
while (true) {
if (zzCurrentPosL < zzEndReadL)
zzInput = zzBufferL[zzCurrentPosL++];
else if (zzAtEOF) {
zzInput = YYEOF;
break zzForAction;
} else {
// store back cached positions
zzCurrentPos = zzCurrentPosL;
zzMarkedPos = zzMarkedPosL;
boolean eof = zzRefill();
// get translated positions and possibly new buffer
zzCurrentPosL = zzCurrentPos;
zzMarkedPosL = zzMarkedPos;
zzBufferL = zzBuffer;
zzEndReadL = zzEndRead;
if (eof) {
zzInput = YYEOF;
break zzForAction;
} else {
zzInput = zzBufferL[zzCurrentPosL++];
}
}
int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]];
if (zzNext == -1) break zzForAction;
zzState = zzNext;
int zzAttributes = zzAttrL[zzState];
if ((zzAttributes & 1) == 1) {
zzAction = zzState;
zzMarkedPosL = zzCurrentPosL;
if ((zzAttributes & 8) == 8) break zzForAction;
}
}
}
// store back cached position
zzMarkedPos = zzMarkedPosL;
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
case 11: {
sb.append(yytext());
}
case 25:
break;
case 4: {
sb = null;
sb = new StringBuffer();
yybegin(STRING_BEGIN);
}
case 26:
break;
case 16: {
sb.append('\b');
}
case 27:
break;
case 6: {
return new Yytoken(Yytoken.TYPE_RIGHT_BRACE, null);
}
case 28:
break;
case 23: {
Boolean val = Boolean.valueOf(yytext());
return new Yytoken(Yytoken.TYPE_VALUE, val);
}
case 29:
break;
case 22: {
return new Yytoken(Yytoken.TYPE_VALUE, null);
}
case 30:
break;
case 13: {
yybegin(YYINITIAL);
return new Yytoken(Yytoken.TYPE_VALUE, sb.toString());
}
case 31:
break;
case 12: {
sb.append('\\');
}
case 32:
break;
case 21: {
Double val = Double.valueOf(yytext());
return new Yytoken(Yytoken.TYPE_VALUE, val);
}
case 33:
break;
case 1: {
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR, yycharat(0));
}
case 34:
break;
case 8: {
return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE, null);
}
case 35:
break;
case 19: {
sb.append('\r');
}
case 36:
break;
case 15: {
sb.append('/');
}
case 37:
break;
case 10: {
return new Yytoken(Yytoken.TYPE_COLON, null);
}
case 38:
break;
case 14: {
sb.append('"');
}
case 39:
break;
case 5: {
return new Yytoken(Yytoken.TYPE_LEFT_BRACE, null);
}
case 40:
break;
case 17: {
sb.append('\f');
}
case 41:
break;
case 24: {
try {
int ch = Integer.parseInt(yytext().substring(2), 16);
sb.append((char) ch);
} catch (Exception e) {
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e);
}
}
case 42:
break;
case 20: {
sb.append('\t');
}
case 43:
break;
case 7: {
return new Yytoken(Yytoken.TYPE_LEFT_SQUARE, null);
}
case 44:
break;
case 2: {
Long val = Long.valueOf(yytext());
return new Yytoken(Yytoken.TYPE_VALUE, val);
}
case 45:
break;
case 18: {
sb.append('\n');
}
case 46:
break;
case 9: {
return new Yytoken(Yytoken.TYPE_COMMA, null);
}
case 47:
break;
case 3: {}
case 48:
break;
default:
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
zzAtEOF = true;
return null;
} else {
zzScanError(ZZ_NO_MATCH);
}
}
}
}
}

View file

@ -0,0 +1,59 @@
/*
* $Id: Yytoken.java,v 1.1 2006/04/15 14:10:48 platform Exp $
* Created on 2006-4-15
*/
package org.to2mbn.authlibinjector.internal.org.json.simple.parser;
/**
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
class Yytoken {
public static final int TYPE_VALUE = 0;// JSON primitive value: string,number,boolean,null
public static final int TYPE_LEFT_BRACE = 1;
public static final int TYPE_RIGHT_BRACE = 2;
public static final int TYPE_LEFT_SQUARE = 3;
public static final int TYPE_RIGHT_SQUARE = 4;
public static final int TYPE_COMMA = 5;
public static final int TYPE_COLON = 6;
public static final int TYPE_EOF = -1;// end of file
public int type = 0;
public Object value = null;
public Yytoken(int type, Object value) {
this.type = type;
this.value = value;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
switch (type) {
case TYPE_VALUE:
sb.append("VALUE(").append(value).append(")");
break;
case TYPE_LEFT_BRACE:
sb.append("LEFT BRACE({)");
break;
case TYPE_RIGHT_BRACE:
sb.append("RIGHT BRACE(})");
break;
case TYPE_LEFT_SQUARE:
sb.append("LEFT SQUARE([)");
break;
case TYPE_RIGHT_SQUARE:
sb.append("RIGHT SQUARE(])");
break;
case TYPE_COMMA:
sb.append("COMMA(,)");
break;
case TYPE_COLON:
sb.append("COLON(:)");
break;
case TYPE_EOF:
sb.append("END OF FILE");
break;
}
return sb.toString();
}
}

View file

@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.URL;
@ -54,6 +55,14 @@ public final class IOUtils {
.replace("\r", "");
}
public static UncheckedIOException newUncheckedIOException(String message) throws UncheckedIOException {
return new UncheckedIOException(new IOException(message));
}
public static UncheckedIOException newUncheckedIOException(String message, Throwable cause) throws UncheckedIOException {
return new UncheckedIOException(new IOException(message, cause));
}
private IOUtils() {}
}

View file

@ -0,0 +1,42 @@
package org.to2mbn.authlibinjector.util;
import static org.to2mbn.authlibinjector.util.IOUtils.newUncheckedIOException;
import java.io.UncheckedIOException;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONArray;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONObject;
import org.to2mbn.authlibinjector.internal.org.json.simple.JSONValue;
import org.to2mbn.authlibinjector.internal.org.json.simple.parser.ParseException;
public final class JsonUtils {
public static Object parseJson(String jsonText) throws UncheckedIOException {
try {
return JSONValue.parse(jsonText);
} catch (ParseException e) {
throw newUncheckedIOException("Invalid JSON", e);
}
}
public static JSONObject asObject(Object json) throws UncheckedIOException {
return assertJson(json, JSONObject.class, "an object");
}
public static JSONArray asArray(Object json) throws UncheckedIOException {
return assertJson(json, JSONArray.class, "an array");
}
public static String asString(Object json) throws UncheckedIOException {
return assertJson(json, String.class, "a string");
}
@SuppressWarnings("unchecked")
private static <T> T assertJson(Object json, Class<T> type, String message) {
if (type.isInstance(json)) {
return (T) json;
}
throw newUncheckedIOException("Invalid JSON: not " + message + ": " + json);
}
private JsonUtils() {}
}

View file

@ -1,6 +1,8 @@
package org.to2mbn.authlibinjector.util;
import static org.to2mbn.authlibinjector.util.IOUtils.newUncheckedIOException;
import static org.to2mbn.authlibinjector.util.IOUtils.removeNewLines;
import java.io.UncheckedIOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
@ -9,7 +11,7 @@ import java.util.Base64;
public final class KeyUtils {
public static byte[] decodePublicKey(String pem) throws IllegalArgumentException {
public static byte[] decodePEMPublicKey(String pem) throws IllegalArgumentException {
pem = removeNewLines(pem);
final String header = "-----BEGIN PUBLIC KEY-----";
final String end = "-----END PUBLIC KEY-----";
@ -21,10 +23,18 @@ public final class KeyUtils {
}
}
public static PublicKey loadX509PublicKey(byte[] encodedKey) throws GeneralSecurityException {
public static PublicKey parseX509PublicKey(byte[] encodedKey) throws GeneralSecurityException {
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encodedKey));
}
public static PublicKey parseSignaturePublicKey(String pem) throws UncheckedIOException {
try {
return parseX509PublicKey(decodePEMPublicKey(pem));
} catch (IllegalArgumentException | GeneralSecurityException e) {
throw newUncheckedIOException("Bad signature public key", e);
}
}
private KeyUtils() {}
}

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,23 +0,0 @@
============================================================================
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,7 +1,7 @@
package org.to2mbn.authlibinjector.test;
import static org.junit.Assert.assertArrayEquals;
import static org.to2mbn.authlibinjector.util.KeyUtils.decodePublicKey;
import static org.to2mbn.authlibinjector.util.KeyUtils.decodePEMPublicKey;
import org.junit.Test;
public class KeyUtilsTest {
@ -9,23 +9,23 @@ public class KeyUtilsTest {
@Test
public void testDecodePublicKey1() {
assertArrayEquals(new byte[] { 127, 127, 127, 127 },
decodePublicKey("-----BEGIN PUBLIC KEY-----f39/fw==-----END PUBLIC KEY-----"));
decodePEMPublicKey("-----BEGIN PUBLIC KEY-----f39/fw==-----END PUBLIC KEY-----"));
}
@Test
public void testDecodePublicKey2() {
assertArrayEquals(new byte[] { 127, 127, 127, 127 },
decodePublicKey("-----BEGIN PUBLIC KEY-----\nf\n39/fw==\n-----END PUBLIC KEY-----\n"));
decodePEMPublicKey("-----BEGIN PUBLIC KEY-----\nf\n39/fw==\n-----END PUBLIC KEY-----\n"));
}
@Test(expected = IllegalArgumentException.class)
public void testDecodePublicKey3() {
decodePublicKey("-----BEGIN PUBLIC KEY----- f39/fw== -----END PUBLIC KEY-----");
decodePEMPublicKey("-----BEGIN PUBLIC KEY----- f39/fw== -----END PUBLIC KEY-----");
}
@Test(expected = IllegalArgumentException.class)
public void testDecodePublicKey4() {
decodePublicKey("-----BEGIN PUBLIC KEY-----f39/fw==-----END NOT A PUBLIC KEY-----");
decodePEMPublicKey("-----BEGIN PUBLIC KEY-----f39/fw==-----END NOT A PUBLIC KEY-----");
}
}