1. Removed all changes to Java SE APIs
2. Changed module name to jdk.management.rest
3. Rest Adapter invoked via Module service provider
4. changed package name to jdk.internal.management.remote.rest
5. rest module and httpserver module part of platform modules
--- a/make/CompileJavaModules.gmk Fri Jan 05 13:42:53 2018 +0530
+++ b/make/CompileJavaModules.gmk Fri Jan 19 13:46:27 2018 +0530
@@ -248,7 +248,7 @@
################################################################################
-java.management.rest_ADD_JAVAC_FLAGS := -Xdoclint:none '-Xdoclint/package:javax.*'
+jdk.management.rest_ADD_JAVAC_FLAGS := -Xdoclint:none '-Xdoclint/package:javax.*'
################################################################################
--- a/make/common/Modules.gmk Fri Jan 05 13:42:53 2018 +0530
+++ b/make/common/Modules.gmk Fri Jan 19 13:46:27 2018 +0530
@@ -53,7 +53,6 @@
java.logging \
java.management \
java.management.rmi \
- java.management.rest \
java.naming \
java.prefs \
java.rmi \
@@ -63,7 +62,6 @@
jdk.management \
jdk.management.agent \
jdk.net \
- jdk.httpserver \
jdk.sctp \
jdk.unsupported \
#
@@ -105,6 +103,7 @@
java.scripting \
java.security.jgss \
java.smartcardio \
+ jdk.management.rest \
java.sql \
java.sql.rowset \
java.xml.crypto \
@@ -119,6 +118,7 @@
jdk.jsobject \
jdk.localedata \
jdk.naming.dns \
+ jdk.httpserver \
jdk.scripting.nashorn \
jdk.security.auth \
jdk.security.jgss \
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpResponse.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ReflectionException;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.mapper.JSONDataException;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.HttpURLConnection;
-
-/**
- * @author harsha
- */
-public class HttpResponse {
-
- public static final HttpResponse OK = new HttpResponse(HttpURLConnection.HTTP_OK, "Success");
- public static final HttpResponse SERVER_ERROR = new HttpResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, "Internal server error");
- public static final HttpResponse METHOD_NOT_ALLOWED = new HttpResponse(HttpURLConnection.HTTP_BAD_METHOD, "Method not allowed");
- public static final HttpResponse BAD_REQUEST = new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Bad request");
- public static final HttpResponse REQUEST_NOT_FOUND = new HttpResponse(HttpURLConnection.HTTP_NOT_FOUND, "Request not found");
-
- private final int code;
- private final String message;
- private final String body;
-
- public HttpResponse(int code, String message) {
- this(code, message, "");
- }
-
- public HttpResponse(String message) {
- this(200,message,"");
- }
-
- public HttpResponse(int code, String message, String detail) {
- this.code = code;
- this.message = message;
-
- if (code != HttpURLConnection.HTTP_OK) {
- JSONObject jobj = new JSONObject();
- jobj.put("status", new JSONPrimitive(code));
- jobj.put("message", new JSONPrimitive(message));
- if (detail != null && !detail.isEmpty()) {
- jobj.put("details", new JSONPrimitive(detail));
- }
- this.body = jobj.toJsonString();
- } else {
- this.body = message;
- }
- }
-
- public HttpResponse(HttpResponse response, String detail) {
- this(response.code, response.message, detail);
- }
-
- public int getCode() {
- return code;
- }
-
- public String getBody() {
- return body;
- }
-
- static int getHttpErrorCode(Exception ex) {
- if (ex instanceof JSONDataException
- || ex instanceof ParseException || ex instanceof IllegalArgumentException) {
- return HttpURLConnection.HTTP_BAD_REQUEST;
- } else if (ex instanceof JSONMappingException) {
- return HttpURLConnection.HTTP_INTERNAL_ERROR;
- } else if (ex instanceof AttributeNotFoundException
- || ex instanceof InstanceNotFoundException
- || ex instanceof ReflectionException) {
- return HttpURLConnection.HTTP_NOT_FOUND;
- }
- return HttpURLConnection.HTTP_BAD_REQUEST;
- }
-
- public static String getErrorMessage(Exception ex) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- ex.printStackTrace(pw);
- return sw.toString();
- }
-
- static JSONObject getJsonObject(int code, JSONElement request, JSONElement response) {
- JSONObject jobj = new JSONObject();
- jobj.put("status", new JSONPrimitive(code));
- jobj.put("request", request);
- jobj.put("response", response);
- return jobj;
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/HttpUtil.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.sun.net.httpserver.Headers;
-import com.sun.net.httpserver.HttpExchange;
-
-import javax.management.remote.rest.PlatformRestAdapter;
-import java.io.*;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-public class HttpUtil {
-
- public static String getRequestCharset(HttpExchange ex) {
- String charset = null;
- List<String> contentType = ex.getRequestHeaders().get("Content-type");
- if (contentType != null) {
- for (String kv : contentType) {
- for (String value : kv.split(";")) {
- value = value.trim();
- if (value.toLowerCase().startsWith("charset=")) {
- charset = value.substring("charset=".length());
- }
- }
- }
- }
- return charset;
- }
-
- public static String getAcceptCharset(HttpExchange ex) {
- List<String> acceptCharset = ex.getRequestHeaders().get("Accept-Charset");
- if (acceptCharset != null && acceptCharset.size() > 0) {
- return acceptCharset.get(0);
- }
- return null;
- }
-
- public static String getGetRequestResource(HttpExchange ex) throws UnsupportedEncodingException {
- String charset = getRequestCharset(ex);
- String httpHandlerPath = ex.getHttpContext().getPath();
- String requestURIpath = ex.getRequestURI().getPath();
- String getRequestPath = requestURIpath.substring(httpHandlerPath.length());
- if (charset != null) {
- return URLDecoder.decode(getRequestPath, charset);
- } else {
- return getRequestPath;
- }
- }
-
- public static String getGetRequestQuery(HttpExchange ex) throws UnsupportedEncodingException {
- String charset = getRequestCharset(ex);
- String query = ex.getRequestURI().getQuery();
- if (charset != null && query != null) {
- return URLDecoder.decode(query, charset);
- } else {
- return query;
- }
- }
-
- public static Map<String, String> getGetRequestQueryMap(HttpExchange ex)
- throws UnsupportedEncodingException {
- String query = ex.getRequestURI().getQuery();
- Map<String, String> queryParams = new LinkedHashMap<>();
-
- if (query == null || query.isEmpty()) {
- return queryParams;
- }
- query = URLDecoder.decode(query, StandardCharsets.UTF_8.displayName());
- String[] params = query.trim().split("&");
- for (String param : params) {
- int idx = param.indexOf('=');
- if (idx != -1) {
- queryParams.put(param.substring(0, idx), param.substring(idx + 1));
- }
- }
- return queryParams;
- }
-
- public static String getCredentials(HttpExchange exchange) {
- Headers rmap = exchange.getRequestHeaders();
- String auth = rmap.getFirst("Authorization");
- if (auth != null && !auth.isEmpty()) {
- int sp = auth.indexOf(' ');
- byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1));
- String authCredentials = new String(b);
- int colon = authCredentials.indexOf(':');
- return authCredentials.substring(0, colon);
- }
- return "";
- }
-
- public static String readRequestBody(HttpExchange he) throws IOException {
- String charset = getRequestCharset(he);
- StringBuilder stringBuilder = new StringBuilder();
- InputStreamReader in = charset != null ? new InputStreamReader(he.getRequestBody(), charset) : new InputStreamReader(he.getRequestBody());
- BufferedReader br = new BufferedReader(in);
- String line;
- while ((line = br.readLine()) != null) {
- String decode = charset != null ? URLDecoder.decode(line, charset) : line;
- stringBuilder.append(decode);
- }
- return stringBuilder.toString();
- }
-
- public static void sendResponse(HttpExchange exchange, HttpResponse response) throws IOException {
- String charset = getRequestCharset(exchange);
- String acceptCharset = HttpUtil.getAcceptCharset(exchange);
- if (acceptCharset != null) {
- charset = acceptCharset;
- }
-
- // Set response headers explicitly
- String msg = charset == null ? response.getBody() : URLEncoder.encode(response.getBody(), charset);
- byte[] bytes = msg.getBytes();
- Headers resHeaders = exchange.getResponseHeaders();
- if (charset != null && !charset.isEmpty()) {
- resHeaders.add("Content-Type", "application/json; charset=" + charset);
- } else {
- resHeaders.add("Content-Type", "application/json;");
- }
-
- exchange.sendResponseHeaders(response.getCode(), bytes.length);
- try (OutputStream os = exchange.getResponseBody()) {
- os.write(bytes);
- }
- }
-
- public static <T> List<T> filterByPage(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
-
- Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
- int currPage = 1;
- if (queryParams != null && !queryParams.isEmpty()) {
- String pageStr = queryParams.get("page");
- if (pageStr != null && !pageStr.isEmpty()) {
- currPage = Integer.parseInt(pageStr);
- currPage = currPage > 1 ? currPage : 1;
- }
- }
-
- if (input.size() <= pageSize) {
- return input;
- }
-
- int start = (currPage - 1) * pageSize;
- int end = Math.min(input.size(), start + pageSize);
- if (start < end) {
- return input.subList(start, end);
- } else {
- return null;
- }
- }
-
- public static <T> JSONObject getPaginationLinks(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
-
- if (pageSize >= input.size()) {
- return null;
- }
-
- Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
- int currPage = 1;
- if (queryParams != null && !queryParams.isEmpty()) {
- String pageStr = queryParams.get("page");
- if (pageStr != null && !pageStr.isEmpty()) {
- currPage = Integer.parseInt(pageStr);
- }
- }
- String path = PlatformRestAdapter.getDomain() + exchange.getRequestURI().getPath() + "?";
- Map<String, String> queryMap = getGetRequestQueryMap(exchange);
- if (queryMap != null) {
- queryMap.remove("page");
- if (!queryMap.isEmpty()) {
- String query = queryMap.keySet().stream()
- .map(k -> k + "=" + queryMap.get(k))
- .collect(Collectors.joining("&"));
- path = path + query + "&";
- }
- }
- int totalPages = (input.size() % pageSize == 0) ? input.size() / pageSize : input.size() / pageSize + 1;
-
- JSONObject jobj = new JSONObject();
- jobj.put("first", path.replaceAll(".$", ""));
- if (currPage == 2) {
- jobj.put("prev", path.replaceAll(".$", ""));
- } else if (currPage > 2) {
- jobj.put("prev", path + "page=" + (currPage - 1));
- }
- if (currPage < totalPages) {
- jobj.put("next", path + "page=" + (currPage + 1));
- }
- jobj.put("last", path + "page=" + totalPages);
-
- return jobj;
- }
-
- public static String escapeUrl(String input) {
- try {
- URL url = new URL(input);
- URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
- return uri.toURL().toString();
- } catch (Exception ex) {
- return null;
- }
- }
-
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanCollectionResource.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import com.oracle.jmx.remote.rest.mapper.JSONMapper;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
-import com.sun.net.httpserver.HttpExchange;
-
-import javax.management.*;
-import javax.management.remote.rest.PlatformRestAdapter;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-public class MBeanCollectionResource implements RestResource, NotificationListener {
-
- private List<ObjectName> allowedMbeans;
- private final MBeanServer mBeanServer;
- private final Map<ObjectName, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>();
- private static final int pageSize = 10;
- private static final String pathPrefix = "^/?jmx/servers/[a-zA-Z0-9\\-\\.]+/mbeans";
-
- // Only MXBean or any other MBean that uses types
- // that have a valid mapper functions
- private boolean isMBeanAllowed(ObjectName objName) {
- try {
- MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName);
-
- // Return true for MXbean
- Descriptor desc = mInfo.getDescriptor();
- String isMxBean = (String) desc.getFieldValue("mxbean");
- if (isMxBean != null && isMxBean.equalsIgnoreCase("true"))
- return true;
-
- // Check attribute types
- MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes();
- for (MBeanAttributeInfo attrInfo : attrsInfo) {
- String type = attrInfo.getType();
- if (!JSONMappingFactory.INSTANCE.isTypeMapped(type)) {
- return false;
- }
- }
-
- // Check operation parameters and return types
- MBeanOperationInfo[] operations = mInfo.getOperations();
- for (MBeanOperationInfo opInfo : operations) {
- MBeanParameterInfo[] signature = opInfo.getSignature();
- for (MBeanParameterInfo sig : signature) {
- if (!JSONMappingFactory.INSTANCE.isTypeMapped(sig.getType())) {
- return false;
- }
- }
- if (!JSONMappingFactory.INSTANCE.isTypeMapped(opInfo.getReturnType())) {
- return false;
- }
- }
- return true;
- } catch (InstanceNotFoundException | IntrospectionException |
- ReflectionException | ClassNotFoundException ex) {
- ex.printStackTrace();
- return false;
- }
- }
-
- private void introspectMBeanTypes(MBeanServer server) {
- if (allowedMbeans.isEmpty()) {
- Set<ObjectInstance> allMBeans = server.queryMBeans(null, null); // get all Mbeans
- allMBeans.stream().filter((objIns) -> (isMBeanAllowed(objIns.getObjectName())))
- .forEachOrdered(objIns -> allowedMbeans.add(objIns.getObjectName()));
- }
- }
-
- @Override
- public void handleNotification(Notification notification, Object handback) {
- try {
- MBeanServerNotification mbs = (MBeanServerNotification) notification;
- if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
- ObjectName mBeanName = mbs.getMBeanName();
- if (isMBeanAllowed(mBeanName)) {
- allowedMbeans.add(mBeanName);
- }
- } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
- if (allowedMbeans.contains(mbs.getMBeanName())) {
- allowedMbeans.remove(mbs.getMBeanName());
- }
- }
- } catch (Exception e) {
- }
- }
-
- public MBeanCollectionResource(MBeanServer mBeanServer) {
- this.mBeanServer = mBeanServer;
- allowedMbeans = new ArrayList<>();
- introspectMBeanTypes(mBeanServer);
- allowedMbeans = new CopyOnWriteArrayList<>(allowedMbeans);
-
- // Create a REST handler for each MBean
- allowedMbeans.forEach(objectName -> mBeanResourceMap.put(objectName,
- new MBeanResource(mBeanServer, objectName)));
- }
-
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.name());
-
- if (path.matches(pathPrefix + "/?$")) {
- RestResource.super.handle(exchange);
- } else if (path.matches(pathPrefix + "/[^/]+/?.*")) {
- // Extract mbean name
- // Forward the request to its corresponding rest resource
- Pattern mbeans = Pattern.compile(pathPrefix + "/");
- Matcher matcher = mbeans.matcher(path);
-
- if (matcher.find()) {
- String ss = path.substring(matcher.end());
- String mBeanName = ss;
- if (ss.indexOf('/') != -1) {
- mBeanName = ss.substring(0, ss.indexOf('/'));
- }
- try {
- MBeanResource mBeanResource = mBeanResourceMap.get(new ObjectName(mBeanName));
- if (mBeanResource == null) {
- HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
- return;
- }
- mBeanResource.handle(exchange);
- } catch (MalformedObjectNameException e) {
- HttpUtil.sendResponse(exchange, HttpResponse.BAD_REQUEST);
- }
-
- }
- }
- }
-
- @Override
- public HttpResponse doGet(HttpExchange exchange) {
- try {
- final String path = PlatformRestAdapter.getDomain()
- + URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName())
- .replaceAll("/$", "");
- List<ObjectName> filteredMBeans = allowedMbeans;
- Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange);
- String query = exchange.getRequestURI().getQuery();
- if (query != null && queryMap.isEmpty()) {
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- "Invalid query params : Allowed query keys [objectname,page]");
- } else if (query != null && !queryMap.isEmpty()) {
- Map<String, String> newMap = new HashMap<>(queryMap);
- newMap.remove("objectname");
- newMap.remove("page");
- if (!newMap.isEmpty()) { // Invalid query params
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- "Invalid query params : Allowed query keys [objectname,page]");
- }
- }
- if (queryMap.containsKey("objectname")) { // Filter based on ObjectName query
- Set<ObjectName> queryMBeans = mBeanServer
- .queryNames(new ObjectName(queryMap.get("objectname")), null);
- queryMBeans.retainAll(allowedMbeans); // Intersection of two lists
- filteredMBeans = new ArrayList<>(queryMBeans);
- }
-
- JSONObject _links = HttpUtil.getPaginationLinks(exchange, filteredMBeans, pageSize);
- List<ObjectName> mbeanPage = HttpUtil.filterByPage(exchange, filteredMBeans, pageSize);
-
- List<Map<String, String>> items = new ArrayList<>(filteredMBeans.size());
- for (ObjectName objectName : mbeanPage) {
- Map<String, String> item = new LinkedHashMap<>();
- item.put("name", objectName.getCanonicalName());
- MBeanResource mBeanResource = mBeanResourceMap.get(objectName);
- try {
- JSONObject mBeanInfo = mBeanResource.getMBeanInfo(mBeanServer, objectName);
- JSONElement element = mBeanInfo.get("descriptor");
- if (element != null) {
- JSONElement element1 = ((JSONObject) element).get("interfaceClassName");
- if (element1 != null) {
- String intfName = (String) ((JSONPrimitive) element1).getValue();
- item.put("interfaceClassName", intfName);
- }
- }
- element = mBeanInfo.get("className");
- if (element != null) {
- String className = (String) ((JSONPrimitive) element).getValue();
- item.put("className", className);
- }
- element = mBeanInfo.get("description");
- if (element != null) {
- String description = (String) ((JSONPrimitive) element).getValue();
- item.put("description", description);
- }
- element = mBeanInfo.get("attributeInfo");
- if (element != null) {
- item.put("attributeCount", ((JSONArray) element).size() + "");
- }
- element = mBeanInfo.get("operationInfo");
- if (element != null) {
- item.put("operationCount", ((JSONArray) element).size() + "");
- }
-
- } catch (InstanceNotFoundException | IntrospectionException | ReflectionException e) {
- }
-
- String href = path + "/" + objectName.toString();
- href = HttpUtil.escapeUrl(href);
- item.put("href", href);
- items.add(item);
- String info = HttpUtil.escapeUrl(href + "/info");
- item.put("info", info);
- }
-
- Map<String, String> properties = new HashMap<>();
-
- properties.put("mbeanCount", Integer.toString(filteredMBeans.size()));
-
- JSONMapper typeMapper1 = JSONMappingFactory.INSTANCE.getTypeMapper(items);
- JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties);
-
- JSONElement linkElem = typeMapper1.toJsonValue(items);
- JSONElement propElem = typeMapper2.toJsonValue(properties);
- JSONObject jobj = new JSONObject();
-
- jobj.putAll((JSONObject) propElem);
- jobj.put("mbeans", linkElem);
-
- if (_links != null && !_links.isEmpty()) {
- jobj.put("_links", _links);
- }
- return new HttpResponse(jobj.toJsonString());
- } catch (JSONMappingException e) {
- return HttpResponse.SERVER_ERROR;
- } catch (UnsupportedEncodingException e) {
- return HttpResponse.BAD_REQUEST;
- } catch (MalformedObjectNameException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
- }
- }
-
- @Override
- public HttpResponse doPost(HttpExchange exchange) {
- try {
- String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName());
- String reqBody = null;
- if (path.matches(pathPrefix + "/?$")) { // POST to current URL
- reqBody = HttpUtil.readRequestBody(exchange);
- if (reqBody == null || reqBody.isEmpty()) { // No Parameters
- return HttpResponse.BAD_REQUEST;
- }
-
- JSONParser parser = new JSONParser(reqBody);
- JSONElement jsonElement = parser.parse();
- if (!(jsonElement instanceof JSONObject)) {
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- "Invalid parameters : [" + reqBody + "]");
- }
-
- JSONObject jsonObject = (JSONObject) jsonElement;
- JSONObject normalizedObject = new JSONObject(jsonObject);
-
- // Normalize the input MBean names
- for (String objectNameString : jsonObject.keySet()) {
- if (!objectNameString.startsWith("?")) { // Ignore object name patterns
- JSONElement element = jsonObject.get(objectNameString);
- normalizedObject.remove(objectNameString);
- normalizedObject.put(new ObjectName(objectNameString).getCanonicalName(), element);
- }
- }
-
- jsonObject.clear();
- jsonObject = normalizedObject;
-
- Set<String> objectNamePatterns = jsonObject.keySet()
- .stream()
- .filter(a -> a.startsWith("?"))
- .collect(Collectors.toSet());
-
- if (!objectNamePatterns.isEmpty()) {
- for (String pattern : objectNamePatterns) {
- Set<ObjectName> queryMBeans = mBeanServer
- .queryNames(new ObjectName(pattern.substring(1)), null);
- queryMBeans.retainAll(allowedMbeans);
- JSONElement patternNode = jsonObject.get(pattern);
- jsonObject.remove(pattern);
- for (ObjectName queryMBean : queryMBeans) {
- String name = queryMBean.getCanonicalName();
- if (jsonObject.containsKey(name)) {
- JSONObject obj = new JSONObject();
- obj.put(name, patternNode);
- deepMerge(jsonObject, obj);
- } else {
- jsonObject.put(name, patternNode);
- }
- }
- }
- }
-
- JSONObject result = new JSONObject();
- for (String mBeanName : jsonObject.keySet()) {
- MBeanResource mBeanResource = mBeanResourceMap.get(new ObjectName(mBeanName));
- if (mBeanResource != null) {
- JSONElement element = jsonObject.get(mBeanName);
- if (element instanceof JSONObject) {
- JSONElement res = mBeanResource.handleBulkRequest
- ((JSONObject) element);
- result.put(mBeanName, res);
- } else {
- result.put(mBeanName, "Invalid input");
- }
- } else {
- result.put(mBeanName, "Invalid MBean");
- }
- }
- return new HttpResponse(result.toJsonString());
- } else {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
- } catch (ParseException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid JSON String for request body");
- } catch (IOException e) {
- return HttpResponse.BAD_REQUEST;
- } catch (MalformedObjectNameException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
- }
- }
-
- private JSONObject deepMerge(JSONObject jsonObject1, JSONObject jsonObject2) {
- for (String key : jsonObject2.keySet()) {
- if (jsonObject1.containsKey(key)) {
- if (jsonObject2.get(key) instanceof JSONObject && jsonObject1.get(key) instanceof JSONObject) {
- JSONObject jobj1 = (JSONObject) jsonObject1.get(key);
- JSONObject jobj2 = (JSONObject) jsonObject2.get(key);
- jsonObject1.put(key, deepMerge(jobj1, jobj2));
- } else if (jsonObject2.get(key) instanceof JSONArray && jsonObject1.get(key) instanceof JSONArray) {
- JSONArray array1 = (JSONArray) jsonObject1.get(key);
- JSONArray array2 = (JSONArray) jsonObject2.get(key);
- for (JSONElement each : array2) {
- if (!array1.contains(each)) {
- array1.add(each);
- }
- }
- } else {
- JSONArray array = new JSONArray();
- array.add(jsonObject1.get(key));
- array.add(jsonObject2.get(key));
- jsonObject1.put(key, array);
- }
- } else {
- jsonObject1.put(key, jsonObject2.get(key));
- }
- }
- return jsonObject1;
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,717 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import com.oracle.jmx.remote.rest.json.parser.TokenMgrError;
-import com.oracle.jmx.remote.rest.mapper.JSONDataException;
-import com.oracle.jmx.remote.rest.mapper.JSONMapper;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
-import com.sun.net.httpserver.HttpExchange;
-
-import javax.management.*;
-import javax.management.openmbean.OpenMBeanAttributeInfo;
-import javax.management.openmbean.OpenMBeanParameterInfo;
-import javax.management.openmbean.OpenType;
-import javax.management.remote.rest.PlatformRestAdapter;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static javax.management.MBeanOperationInfo.*;
-
-public class MBeanResource implements RestResource {
-
- private final ObjectName objectName;
- private final MBeanServer mBeanServer;
- private static final String pathPrefix = "^/?jmx/servers/[^/]+/mbeans/[^/]+";
-
- private final static Map<String, Class<?>> primitiveToObject = new HashMap<>();
-
- static {
- primitiveToObject.put("int", Integer.TYPE);
- primitiveToObject.put("long", Long.TYPE);
- primitiveToObject.put("double", Double.TYPE);
- primitiveToObject.put("float", Float.TYPE);
- primitiveToObject.put("boolean", Boolean.TYPE);
- primitiveToObject.put("char", Character.TYPE);
- primitiveToObject.put("byte", Byte.TYPE);
- primitiveToObject.put("void", Void.TYPE);
- primitiveToObject.put("short", Short.TYPE);
- }
-
- MBeanResource(MBeanServer mBeanServer, ObjectName objectName) {
- this.mBeanServer = mBeanServer;
- this.objectName = objectName;
- }
-
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName());
- if (path.matches(pathPrefix + "/?$")) {
- RestResource.super.handle(exchange);
- } else if (path.matches(pathPrefix + "/info$")
- && exchange.getRequestMethod().equalsIgnoreCase("GET")) {
- RestResource.super.handle(exchange);
- } else if (path.matches(pathPrefix + "/[^/]+/?$")
- && exchange.getRequestMethod().equalsIgnoreCase("POST")) {
- RestResource.super.handle(exchange);
- } else {
- HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
- }
- }
-
- @Override
- public HttpResponse doGet(HttpExchange exchange) {
- String path = PlatformRestAdapter.getDomain() +
- exchange.getRequestURI().getPath().replaceAll("/$", "");
-
- try {
- path = URLDecoder.decode(path, StandardCharsets.UTF_8.displayName());
- if (path.endsWith("info")) {
- return doMBeanInfo();
- }
-
- String infoPath = path + "/info";
-
- Map<String, Object> allAttributes = getAllAttributes();
- Map<String, String> _links = new LinkedHashMap<>();
- //_links.put("info", HttpUtil.escapeUrl(infoPath));
-
- MBeanOperationInfo[] opInfo = mBeanServer.getMBeanInfo(objectName).getOperations();
- JSONArray jarr = new JSONArray();
- for (MBeanOperationInfo op : opInfo) {
- JSONObject jobj1 = new JSONObject();
- JSONArray jarr1 = new JSONArray();
- jobj1.put("name", op.getName());
- jobj1.put("href", HttpUtil.escapeUrl(path + "/" + op.getName()));
- jobj1.put("method", "POST");
- for (MBeanParameterInfo paramInfo : op.getSignature()) {
- JSONObject jobj = new JSONObject();
- jobj.put("name", paramInfo.getName());
- jobj.put("type", paramInfo.getType());
- jarr1.add(jobj);
- }
- jobj1.put("arguments", jarr1);
- jobj1.put("returnType", op.getReturnType());
- jarr.add(jobj1);
- }
-
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(allAttributes);
- if (typeMapper != null) {
- JSONElement jsonElement1 = typeMapper.toJsonValue(allAttributes);
- JSONElement jsonElement2 = typeMapper.toJsonValue(_links);
-
- JSONObject jobj = new JSONObject();
- jobj.put("attributes", jsonElement1);
- jobj.put("operations", jarr);
- return new HttpResponse(jobj.toJsonString());
- } else {
- return HttpResponse.SERVER_ERROR;
- }
- } catch (RuntimeOperationsException | IntrospectionException | ReflectionException
- | JSONMappingException | MBeanException e) {
- return HttpResponse.SERVER_ERROR;
- } catch (InstanceNotFoundException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
- } catch (Exception e) {
- return HttpResponse.SERVER_ERROR;
- }
- }
-
- /*
- HTTP POST for this MBean's URL allows setting of attributes and execution of operations.
- POST request body can follow one of the below formats
- 1. { name : value}
- Set a single attribute
- 2. { name1 : value1, name2 : value2 }
- Sets multiple attributes
- 3. {attributes : {read : [name]} , {write : {name : value}}, operations : {op_name : {param_name:name, param_value:value}}}
- This bulk operation request sets multiple attributes and executes multiple
- operations on the MBean.
- */
- @Override
- public HttpResponse doPost(HttpExchange exchange) {
- String path = exchange.getRequestURI().getPath();
- String reqBody = null;
- try {
- if (path.matches(pathPrefix + "/?$")) { // POST to current URL
- reqBody = HttpUtil.readRequestBody(exchange);
- if (reqBody.isEmpty()) { // No Parameters
- return HttpResponse.BAD_REQUEST;
- }
-
- JSONParser parser = new JSONParser(reqBody);
- JSONElement jsonElement = parser.parse();
- if (!(jsonElement instanceof JSONObject)) {
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- "Invalid parameters : [" + reqBody + "]");
- }
-
- JSONObject jsonObject = (JSONObject) jsonElement;
-
- // Handle bulk operation
- if (jsonObject.keySet().contains("attributes") | jsonObject.keySet().contains("operations")) {
- return new HttpResponse(handleBulkRequest(jsonObject).toJsonString());
- } else { // Handle attribute update
- Map<String, Object> stringObjectMap = setAttributes(jsonObject);
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(stringObjectMap);
- if (typeMapper != null) {
- return new HttpResponse(HttpURLConnection.HTTP_OK, typeMapper.toJsonValue(stringObjectMap).toJsonString());
- } else {
- return new HttpResponse(HttpResponse.SERVER_ERROR, "Unable to find JSON Mapper");
- }
- }
- } else if (path.matches(pathPrefix + "/[^/]+/?$")) { // POST to MBeanOperation
- Matcher matcher = Pattern.compile(pathPrefix + "/").matcher(path);
- String operation;
- if (matcher.find()) {
- operation = path.substring(matcher.end());
- } else {
- return HttpResponse.BAD_REQUEST;
- }
-
- reqBody = HttpUtil.readRequestBody(exchange);
- JSONElement result;
- if (reqBody.isEmpty()) { // No Parameters
- result = execOperation(operation, null);
- } else {
- JSONParser parser = new JSONParser(reqBody);
- JSONElement jsonElement = parser.parse();
- if (!(jsonElement instanceof JSONObject)) {
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- "Invalid parameters : [" + reqBody + "] for operation - " + operation);
- }
- result = execOperation(operation, (JSONObject) jsonElement);
- }
- return new HttpResponse(HttpURLConnection.HTTP_OK, result.toJsonString());
- } else {
- return HttpResponse.REQUEST_NOT_FOUND;
- }
- } catch (InstanceNotFoundException e) {
- // Should never happen
- } catch (JSONDataException | ParseException | TokenMgrError e) {
- return new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid JSON : " + reqBody, e.getMessage());
- } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException | IOException e) {
- return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
- } catch (IllegalArgumentException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, e.getMessage());
- } catch (Exception e) {
- return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
- }
- return HttpResponse.REQUEST_NOT_FOUND;
- }
-
- private HttpResponse doMBeanInfo() {
- try {
- JSONObject mBeanInfo = getMBeanInfo(mBeanServer, objectName);
- return new HttpResponse(mBeanInfo.toJsonString());
- } catch (RuntimeOperationsException | IntrospectionException | ReflectionException e) {
- return HttpResponse.SERVER_ERROR;
- } catch (InstanceNotFoundException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
- } catch (Exception e) {
- return HttpResponse.SERVER_ERROR;
- }
- }
-
- JSONElement handleBulkRequest(JSONObject reqObject) {
- JSONObject result = new JSONObject();
-
- // Handle attributes
- JSONElement element = reqObject.get("attributes");
- if (element != null && element instanceof JSONObject) {
- JSONObject attrInfo = (JSONObject) element;
- JSONObject attrNode = new JSONObject();
-
- // Read attributes
- JSONElement read = attrInfo.get("get");
- if (read != null) {
- if (read instanceof JSONArray) {
- JSONArray jsonAttrMap = (JSONArray) read;
- JSONElement resultJson;
- Map<String, Object> attrRead;
- try {
- String[] attributes = getStrings(jsonAttrMap);
- attrRead = getAttributes(attributes);
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrRead);
- resultJson = typeMapper.toJsonValue(attrRead);
- } catch (InstanceNotFoundException | ReflectionException | JSONMappingException | MBeanException e) {
- resultJson = new JSONPrimitive("<ERROR: Unable to retrieve value>");
- } catch (JSONDataException e) {
- resultJson = new JSONPrimitive("Invalid JSON : " + e.getMessage());
- }
- attrNode.put("get", resultJson);
- } else {
- attrInfo.put("get", new JSONPrimitive("Invalid JSON : " + read.toJsonString()));
- }
- }
-
- // Write attributes
- JSONElement write = attrInfo.get("set");
-
- if (write != null) {
- if (write instanceof JSONObject) {
- JSONElement resultJson;
- JSONObject jsonAttrMap = (JSONObject) write;
- try {
- Map<String, Object> attrMap = setAttributes(jsonAttrMap);
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrMap);
- resultJson = typeMapper.toJsonValue(attrMap);
- } catch (JSONDataException ex) {
- resultJson = new JSONPrimitive("Invalid JSON : " + write.toJsonString());
- } catch (JSONMappingException | IntrospectionException | InstanceNotFoundException | ReflectionException e) {
- resultJson = new JSONPrimitive("<ERROR: Unable to retrieve value>");
- }
- attrNode.put("set", resultJson);
- } else {
- attrNode.put("set", new JSONPrimitive("Invalid JSON : " + write.toJsonString()));
- }
- }
- result.put("attributes", attrNode);
- }
-
- // Execute operations
- element = reqObject.get("operations");
- if (element != null) {
- JSONArray operationList;
- if (element instanceof JSONPrimitive // Single no-arg operation
- || element instanceof JSONObject) { // single/mulitple operations
- operationList = new JSONArray();
- operationList.add(element);
- } else if (element instanceof JSONArray) { // List of no-arg/with-arg operation
- operationList = (JSONArray) element;
- } else {
- operationList = new JSONArray();
- }
- JSONObject opResult = new JSONObject();
- operationList.forEach((elem) -> {
- if (elem instanceof JSONPrimitive
- && ((JSONPrimitive) elem).getValue() instanceof String) { // no-arg operation
- String opName = (String) ((JSONPrimitive) elem).getValue();
- try {
- JSONElement obj = execOperation(opName, null);
- opResult.put(opName, obj);
- } catch (IllegalArgumentException e) {
- opResult.put(opName, e.getMessage());
- } catch (IntrospectionException | InstanceNotFoundException
- | MBeanException | ReflectionException e) {
- opResult.put(opName, "<ERROR while executing operation>");
- }
- } else if (elem instanceof JSONObject) {
- ((JSONObject) elem).keySet().forEach((opName) -> {
- try {
- JSONElement jsonElement = ((JSONObject) elem).get(opName);
- if (jsonElement instanceof JSONObject) {
- JSONElement obj = execOperation(opName, (JSONObject) jsonElement);
- opResult.put(opName, obj);
- } else {
- opResult.put(opName, new JSONPrimitive("Invalid parameter JSON"));
- }
- } catch (IllegalArgumentException e) {
- opResult.put(opName, e.getMessage());
- } catch (IntrospectionException | InstanceNotFoundException
- | MBeanException | ReflectionException e) {
- opResult.put(opName, "<ERROR while executing operation>");
- }
- });
- }
- });
- result.put("operations", opResult);
- }
- return result;
- }
-
- JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean)
- throws InstanceNotFoundException, IntrospectionException, ReflectionException {
-
- JSONObject jobj = new JSONObject();
- MBeanInfo mBeanInfo = mbeanServer.getMBeanInfo(mbean);
- if (mBeanInfo == null) {
- return jobj;
- }
- jobj.put("name", mbean.getCanonicalName());
- jobj.put("className", mBeanInfo.getClassName());
- jobj.put("description", mBeanInfo.getDescription());
-
- // Populate Attribute Info
- MBeanAttributeInfo[] attributes = mBeanInfo.getAttributes();
- JSONArray jarr = new JSONArray();
- for (MBeanAttributeInfo attr : attributes) {
- String access;
- if (attr.isReadable()) {
- if (attr.isWritable()) {
- access = "read/write";
- } else {
- access = "read-only";
- }
- } else if (attr.isWritable()) {
- access = "write-only";
- } else {
- access = "no-access";
- }
- JSONObject jobj1 = new JSONObject();
- jobj1.put("name", attr.getName());
- jobj1.put("type", attr.getType());
- jobj1.put("access", access);
- jobj1.put("description", attr.getDescription());
- jobj1.put("descriptor", getDescriptorJSON(attr.getDescriptor()));
- jarr.add(jobj1);
- }
- jobj.put("attributeInfo", jarr);
-
-
- // Add constructor Info
- MBeanConstructorInfo[] constructorInfo = mBeanInfo.getConstructors();
- jarr = new JSONArray();
- for (MBeanConstructorInfo constructor : constructorInfo) {
- JSONObject jobj1 = new JSONObject();
- jobj1.put("name", constructor.getName());
- JSONArray jarr1 = new JSONArray();
- for (MBeanParameterInfo paramInfo : constructor.getSignature()) {
- jarr1.add(getParamJSON(paramInfo));
- }
- jobj1.put("signature", jarr1);
- jobj1.put("description", constructor.getDescription());
- if (constructor.getDescriptor().getFieldNames().length > 1) {
- jobj1.put("descriptor", getDescriptorJSON(constructor.getDescriptor()));
- }
- jarr.add(jobj1);
- }
- jobj.put("constructorInfo", jarr);
-
- MBeanOperationInfo[] opInfo = mBeanInfo.getOperations();
- jarr = new JSONArray();
-
- for (MBeanOperationInfo op : opInfo) {
- String impactString;
- switch (op.getImpact()) {
- case ACTION:
- impactString = "action";
- break;
- case ACTION_INFO:
- impactString = "action/info";
- break;
- case INFO:
- impactString = "info";
- break;
- case UNKNOWN:
- impactString = "unknown";
- break;
- default:
- impactString = "(" + op.getImpact() + ")";
- }
-
- JSONObject jobj1 = new JSONObject();
-
- jobj1.put("name", op.getName());
- JSONArray jarr1 = new JSONArray();
- for (MBeanParameterInfo paramInfo : op.getSignature()) {
- jarr1.add(getParamJSON(paramInfo));
- }
- jobj1.put("signature", jarr1);
- jobj1.put("returnType", op.getReturnType());
- jobj1.put("impact", impactString);
- jobj1.put("description", op.getDescription());
- if (op.getDescriptor().getFieldNames().length > 1) {
- jobj1.put("descriptor", getDescriptorJSON(op.getDescriptor()));
- }
- jarr.add(jobj1);
- }
- jobj.put("operationInfo", jarr);
-
- MBeanNotificationInfo[] notifications = mBeanInfo.getNotifications();
- jarr = new JSONArray();
-
- for (MBeanNotificationInfo notification : notifications) {
- JSONObject jobj1 = new JSONObject();
- jobj1.put("name", notification.getName());
- JSONArray jarr1 = new JSONArray();
- for (String notifType : notification.getNotifTypes()) {
- jarr1.add(new JSONPrimitive(notifType));
- }
- jobj1.put("notifTypes", jarr1);
- jobj1.put("description", notification.getDescription());
- if (notification.getDescriptor().getFieldNames().length > 1) {
- jobj1.put("descriptor", getDescriptorJSON(notification.getDescriptor()));
- }
- jarr.add(jobj1);
- }
- jobj.put("notificationInfo", jarr);
-
- jobj.put("descriptor", getDescriptorJSON(mBeanInfo.getDescriptor()));
- return jobj;
- }
-
- private JSONObject getParamJSON(MBeanParameterInfo mParamInfo) {
- JSONObject jobj1 = new JSONObject();
- jobj1.put("name", mParamInfo.getName());
- jobj1.put("type", mParamInfo.getType());
- if (mParamInfo.getDescription() != null && !mParamInfo.getDescription().isEmpty()) {
- jobj1.put("description", mParamInfo.getDescription());
- }
- if (mParamInfo.getDescriptor() != null && mParamInfo.getDescriptor().getFieldNames().length > 1) {
- jobj1.put("descriptor", getDescriptorJSON(mParamInfo.getDescriptor()));
- }
- return jobj1;
- }
-
- private JSONObject getDescriptorJSON(Descriptor descriptor) {
- JSONObject jobj2 = new JSONObject();
- String[] descNames = descriptor.getFieldNames();
- for (String descName : descNames) {
- Object fieldValue = descriptor.getFieldValue(descName);
- jobj2.put(descName, fieldValue != null ? fieldValue.toString() : null);
- }
- return jobj2;
- }
-
- private Map<String, Object> getAttributes(String[] attrs) throws
- InstanceNotFoundException, ReflectionException, MBeanException {
-
- Map<String, Object> result = new LinkedHashMap<>();
-
- if (attrs == null || attrs.length == 0) {
- return result;
- }
-
- AttributeList attrVals = mBeanServer.getAttributes(objectName, attrs);
- List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
- attrVals.asList().forEach(a -> {
- missingAttrs.remove(a.getName());
- result.put(a.getName(), a.getValue());
- });
-
- for (String attr : missingAttrs) {
- try {
- mBeanServer.getAttribute(objectName, attr);
- result.put(attr, "< Error: No such attribute >");
- } catch (RuntimeException ex) {
- if (ex.getCause() instanceof UnsupportedOperationException) {
- result.put(attr, "< Attribute not supported >");
- } else if (ex.getCause() instanceof IllegalArgumentException) {
- result.put(attr, "< Invalid attributes >");
- }
- } catch (AttributeNotFoundException e) {
- result.put(attr, "< Attribute not found >");
- }
- }
- return result;
- }
-
- private Map<String, Object> getAllAttributes() throws InstanceNotFoundException,
- ReflectionException, MBeanException, IntrospectionException {
-
- MBeanInfo mInfo = mBeanServer.getMBeanInfo(objectName);
- String[] attrs = Stream.of(mInfo.getAttributes())
- .map(MBeanAttributeInfo::getName)
- .toArray(String[]::new);
-
- return getAttributes(attrs);
- }
-
- private Map<String, Object> setAttributes(JSONObject attrMap) throws JSONDataException,
- IntrospectionException, InstanceNotFoundException, ReflectionException {
-
- if (attrMap == null || attrMap.isEmpty()) {
- throw new JSONDataException("Null arguments for set attribute");
- }
-
- MBeanInfo mBeanInfo = mBeanServer.getMBeanInfo(objectName);
- Map<String, Object> result = new HashMap<>();
-
- for (String attrName : attrMap.keySet()) {
- MBeanAttributeInfo attrInfo = Arrays.stream(mBeanInfo.getAttributes()).
- filter(a -> a.getName().equals(attrName)).findFirst().orElse(null);
- if (attrInfo == null) {
- result.put(attrName, "<Attribute not found>");
- } else if (!attrInfo.isWritable()) {
- result.put(attrName, "<Attribute is read-only>");
- } else {
- JSONMapper mapper;
- if (attrInfo instanceof OpenMBeanAttributeInfo) {
- OpenType<?> type = ((OpenMBeanAttributeInfo) attrInfo).getOpenType();
- mapper = JSONMappingFactory.INSTANCE.getTypeMapper(type);
- } else {
- Class<?> inputCls = primitiveToObject.get(attrInfo.getType());
- try {
- if (inputCls == null) {
- inputCls = Class.forName(attrInfo.getType());
- }
- } catch (ClassNotFoundException | ClassCastException ex) {
- throw new IllegalArgumentException("Invalid parameters : "
- + attrMap.get(attrName).toJsonString() + " cannot be mapped to : " + attrInfo.getType());
- }
- mapper = JSONMappingFactory.INSTANCE.getTypeMapper(inputCls);
- }
- try {
- Object attrValue = mapper.toJavaObject(attrMap.get(attrName));
- Attribute attrObj = new Attribute(attrName, attrValue);
- mBeanServer.setAttribute(objectName, attrObj);
- result.put(attrName, "success");
- } catch (InvalidAttributeValueException | JSONDataException e) {
- result.put(attrName, "<Invalid value for the attribute>");
- } catch (AttributeNotFoundException e) {
- result.put(attrName, "<Attribute not found>");
- } catch (ReflectionException | InstanceNotFoundException | MBeanException e) {
- result.put(attrName, "<ERROR: Unable to retrieve value>");
- }
- }
- }
- return result;
- }
-
- private Object mapJsonElemToType(JSONElement jsonElement, MBeanParameterInfo type) {
- if (type instanceof OpenMBeanParameterInfo) {
- OpenType<?> openType = ((OpenMBeanParameterInfo) type).getOpenType();
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(openType);
- try {
- return typeMapper.toJavaObject(jsonElement);
- } catch (JSONDataException ex) {
- throw new IllegalArgumentException("Invalid JSON String : " + jsonElement.toJsonString() + " for arguments");
- }
- } else {
- Class<?> inputCls = primitiveToObject.get(type.getType());
- try {
- if (inputCls == null) {
- inputCls = Class.forName(type.getType());
- }
- } catch (ClassNotFoundException | ClassCastException ex) {
- throw new IllegalArgumentException("Invalid parameters : " + jsonElement.toJsonString() + " cannot be mapped to : " + type.getType());
- }
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(inputCls);
- if (typeMapper == null) {
- throw new IllegalArgumentException("Invalid parameters : " + jsonElement.toJsonString() + " cannot be mapped to : " + type.getType());
- }
- try {
- return typeMapper.toJavaObject(jsonElement);
- } catch (JSONDataException ex) {
- throw new IllegalArgumentException("Invalid JSON String : " + jsonElement.toJsonString() + " for arguments");
- }
- }
- }
-
- private Map<String, Object> getOperationParameters(Map<String, JSONElement> jsonValues, Map<String, MBeanParameterInfo> typeMap) {
- if (jsonValues.size() != typeMap.size()) {
- throw new IllegalArgumentException("Invalid parameters : expected - " + typeMap.size() + " parameters, got - " + jsonValues.size());
- }
- if (!jsonValues.keySet().equals(typeMap.keySet())) {
- throw new IllegalArgumentException("Invalid parameters - expected : " + Arrays.toString(typeMap.keySet().toArray()));
- }
- Map<String, Object> parameters = new LinkedHashMap<>(); // Order of parameters should be same as typeMap
- if (typeMap.isEmpty() && jsonValues.isEmpty()) {
- return parameters;
- }
- typeMap.keySet().forEach((name) -> {
- MBeanParameterInfo type = typeMap.get(name);
- JSONElement jsonVal = jsonValues.get(name);
- Object obj = mapJsonElemToType(jsonVal, type);
- parameters.put(name, obj);
- });
- return parameters;
- }
-
- private JSONElement execOperation(String opstr, JSONObject params)
- throws MBeanException, IntrospectionException, ReflectionException, InstanceNotFoundException {
- if (params == null) {
- params = new JSONObject();
- }
- MBeanInfo mBeanInfo;
- try {
- mBeanInfo = mBeanServer.getMBeanInfo(objectName);
- } catch (InstanceNotFoundException ex) {
- throw new IllegalArgumentException("MBean does not exist");
- }
-
- List<MBeanOperationInfo> mBeanOperationInfos = Arrays.stream(mBeanInfo.getOperations()).
- filter(a -> a.getName().equals(opstr)).collect(Collectors.toList());
-
- if (mBeanOperationInfos.isEmpty()) {
- throw new IllegalArgumentException("Invalid Operation String");
- }
-
- String[] signature = null;
- Object[] parameters = null;
-
- IllegalArgumentException exception = null;
- for (MBeanOperationInfo mBeanOperationInfo : mBeanOperationInfos) {
- MBeanParameterInfo[] sig = mBeanOperationInfo.getSignature();
- try {
- Map<String, MBeanParameterInfo> typeMap = new LinkedHashMap<>(); // Order of parameters is important
- Arrays.stream(sig).forEach(e -> typeMap.put(e.getName(), e));
- parameters = getOperationParameters(params, typeMap).values().toArray();
- signature = Stream.of(sig).map(MBeanParameterInfo::getType).toArray(String[]::new);
- exception = null;
- break;
- } catch (IllegalArgumentException ex) {
- exception = ex;
- }
- }
- if (exception != null) {
- throw exception;
- }
-
- Object invoke;
- try {
- invoke = mBeanServer.invoke(objectName, opstr, parameters, signature);
- if (invoke != null) {
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(invoke);
- if (typeMapper != null) {
- return typeMapper.toJsonValue(invoke);
- } else {
- return new JSONPrimitive("<Unable to map result to JSON>");
- }
- } else {
- return new JSONPrimitive("void");
- }
- } catch (JSONMappingException e) {
- return new JSONPrimitive("<Unable to map result to JSON>");
- }
- }
-
- private String[] getStrings(JSONArray jsonArray) throws JSONDataException {
- List<String> attributes = new ArrayList<>();
- for (JSONElement element : jsonArray) {
- if (element instanceof JSONPrimitive && ((JSONPrimitive) element).getValue() instanceof String) {
- JSONPrimitive val = (JSONPrimitive) element;
- attributes.add((String) val.getValue());
- } else throw new JSONDataException("Expecting String, got " + element.toJsonString());
- }
- return attributes.toArray(new String[0]);
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerCollectionResource.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpServer;
-
-import javax.management.remote.rest.PlatformRestAdapter;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-/**
- * This class handles all the HTTP requests for the base URL
- * for REST adapter.
- */
-public class MBeanServerCollectionResource implements RestResource {
-
- private final List<MBeanServerResource> restAdapters;
- private final int pageSize = 5;
-
- public MBeanServerCollectionResource(List<MBeanServerResource> adapters, HttpServer server) {
- this.restAdapters = adapters;
- server.createContext("/jmx/servers", this);
- }
-
- @Override
- public HttpResponse doGet(HttpExchange exchange) {
- try {
- JSONObject _links = HttpUtil.getPaginationLinks(exchange, restAdapters, pageSize);
- List<MBeanServerResource> filteredList = HttpUtil.filterByPage(exchange, restAdapters, pageSize);
- if (filteredList == null) {
- return HttpResponse.OK;
- }
- String query = exchange.getRequestURI().getQuery();
- if (query != null) {
- return HttpResponse.BAD_REQUEST;
- }
- String exchangePath = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName())
- .replaceAll("/$", "");
- if (!exchangePath.equalsIgnoreCase("/jmx/servers")) {
- return HttpResponse.REQUEST_NOT_FOUND;
- }
- final String path = PlatformRestAdapter.getDomain() + exchangePath;
-
- JSONObject root = new JSONObject();
- if (_links != null && !_links.isEmpty()) {
- root.put("_links", _links);
- }
-
- root.put("mBeanServerCount", Integer.toString(restAdapters.size()));
-
- JSONArray list = new JSONArray();
- filteredList.stream().map((adapter) -> {
- JSONObject result = new JSONObject();
- result.put("name", adapter.getContext());
- result.put("href", path + "/" + adapter.getContext());
- return result;
- }).forEachOrdered((result) -> {
- list.add(result);
- });
- root.put("mBeanServers", list);
- return new HttpResponse(HttpURLConnection.HTTP_OK, root.toJsonString());
- } catch (UnsupportedEncodingException e) {
- return new HttpResponse(HttpResponse.BAD_REQUEST,
- HttpUtil.getRequestCharset(exchange) + " is not supported");
- }
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanServerResource.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.mapper.JSONMapper;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingException;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
-import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
-import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
-import com.sun.jmx.remote.security.SubjectDelegator;
-import com.sun.net.httpserver.BasicAuthenticator;
-import com.sun.net.httpserver.HttpContext;
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpServer;
-
-import javax.management.JMX;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerDelegateMBean;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.rest.JmxRestAdapter;
-import javax.management.remote.rest.PlatformRestAdapter;
-import javax.security.auth.Subject;
-import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.HttpURLConnection;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-
-public final class MBeanServerResource implements RestResource, JmxRestAdapter {
-
- // Initialization parameters
- private final HttpServer httpServer;
- private final String contextStr;
- private final Map<String, ?> env;
- private final MBeanServer mbeanServer;
-
- // Save the context to start/stop the adapter
- private HttpContext httpContext;
- private JMXAuthenticator authenticator = null;
- private final MBeanServerDelegateMBean mBeanServerDelegateMBean;
-
- // Save MBeanServer Proxy for a user
- private final MBeanCollectionResource defaultMBeansResource;
- // Use an expiring map that removes entries after the configured period lapses.
- private final TimedMap<String, MBeanCollectionResource> proxyMBeanServers = new TimedMap<>(5*60);
-
- private static AtomicInteger resourceNumber = new AtomicInteger(1);
- private boolean started = false;
-
- public MBeanServerResource(HttpServer hServer, MBeanServer mbeanServer,
- String context, Map<String, ?> env) {
- this.httpServer = hServer;
- this.env = env;
- this.mbeanServer = mbeanServer;
-
- mBeanServerDelegateMBean = JMX.newMBeanProxy(mbeanServer,
- MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
-
- if (context == null || context.isEmpty()) {
- contextStr = "server-" + resourceNumber.getAndIncrement();
- } else {
- contextStr = context;
- }
- // setup authentication
- if (env.get("jmx.remote.x.authentication") != null) {
- authenticator = (JMXAuthenticator) env.get("jmx.remote.authenticator");
- if (authenticator == null) {
- if (env.get("jmx.remote.x.password.file") != null
- || env.get("jmx.remote.x.login.config") != null) {
- authenticator = new JMXPluggableAuthenticator(env);
- } else {
- throw new IllegalArgumentException
- ("Config error : Authentication is enabled with no authenticator");
- }
- }
- }
-
- if (env.get("jmx.remote.x.authentication") == null) {
- defaultMBeansResource = new MBeanCollectionResource(mbeanServer);
- } else {
- defaultMBeansResource = null;
- }
- }
-
- private MBeanServer getMBeanServerProxy(MBeanServer mbeaServer, Subject subject) {
- return (MBeanServer) Proxy.newProxyInstance(MBeanServer.class.getClassLoader(),
- new Class<?>[]{MBeanServer.class},
- new AuthInvocationHandler(mbeaServer, subject));
- }
-
- @Override
- public HttpResponse doGet(HttpExchange exchange) {
- String selfUrl = getUrl();
- Map<String, String> links = new LinkedHashMap<>();
- links.put("mbeans", selfUrl + "/mbeans");
-
- Map<String, Object> mBeanServerInfo = getMBeanServerInfo();
- mBeanServerInfo.put("_links", links);
-
- final JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(mBeanServerInfo);
- if (typeMapper != null) {
- try {
- JSONElement jsonElement = typeMapper.toJsonValue(mBeanServerInfo);
- return new HttpResponse(jsonElement.toJsonString());
- } catch (JSONMappingException e) {
- return HttpResponse.SERVER_ERROR;
- }
- } else {
- return HttpResponse.SERVER_ERROR;
- }
- }
-
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- MBeanCollectionResource mBeansResource = defaultMBeansResource;
- if (env.get("jmx.remote.x.authentication") != null) {
- String authCredentials = HttpUtil.getCredentials(exchange);
- // MBeanServer proxy should be populated in the authenticator
- mBeansResource = proxyMBeanServers.get(authCredentials);
- if (mBeansResource == null) {
- throw new IllegalArgumentException("Invalid HTTP request Headers");
- }
- }
-
- String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName());
- String pathPrefix = httpContext.getPath();
- // Route request to appropriate resource
- if (path.matches(pathPrefix + "/?$")) {
- RestResource.super.handle(exchange);
- } else if (path.matches(pathPrefix + "/mbeans.*")) {
- mBeansResource.handle(exchange);
- } else {
- HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
- }
- }
-
- @Override
- public synchronized void start() {
- if (!started) {
- httpContext = httpServer.createContext("/jmx/servers/" + contextStr, this);
- if (env.get("jmx.remote.x.authentication") != null) {
- httpContext.setAuthenticator(new RestAuthenticator("jmx-rest"));
- }
- started = true;
- }
- }
-
- @Override
- public synchronized void stop() {
- if (!started) {
- throw new IllegalStateException("Rest Adapter not started yet");
- }
- httpServer.removeContext(httpContext);
- started = false;
- }
-
- @Override
- public String getUrl() {
- return PlatformRestAdapter.getBaseURL() + "/" + contextStr;
- }
-
- @Override
- public MBeanServer getMBeanServer() {
- return mbeanServer;
- }
-
- public String getContext() {
- return contextStr;
- }
-
- private class RestAuthenticator extends BasicAuthenticator {
-
- RestAuthenticator(String realm) {
- super(realm);
- }
-
- @Override
- public boolean checkCredentials(String username, String password) {
- if (proxyMBeanServers.containsKey(username)) {
- return true;
- } else {
- Subject subject = null;
- if (authenticator != null) {
- String[] credential = new String[]{username, password};
- try {
- subject = authenticator.authenticate(credential);
- } catch (SecurityException e) {
- return false;
- }
- }
- MBeanServer proxy = getMBeanServerProxy(mbeanServer, subject);
- proxyMBeanServers.put(username, new MBeanCollectionResource(proxy));
- return true;
- }
- }
- }
-
- Map<String, Object> getMBeanServerInfo() {
- Map<String, Object> result = new LinkedHashMap<>();
-
- result.put("id", mBeanServerDelegateMBean.getMBeanServerId());
- result.put("context", contextStr);
-
- result.put("defaultDomain", mbeanServer.getDefaultDomain());
- result.put("mBeanCount", mbeanServer.getMBeanCount());
- result.put("domains", Arrays.toString(mbeanServer.getDomains()));
-
- result.put("specName", mBeanServerDelegateMBean.getSpecificationName());
- result.put("specVersion", mBeanServerDelegateMBean.getSpecificationVersion());
- result.put("specVendor", mBeanServerDelegateMBean.getSpecificationVendor());
-
- result.put("implName", mBeanServerDelegateMBean.getImplementationName());
- result.put("implVersion", mBeanServerDelegateMBean.getImplementationVersion());
- result.put("implVendor", mBeanServerDelegateMBean.getImplementationVendor());
-
- return result;
- }
-
- private class AuthInvocationHandler implements InvocationHandler {
-
- private final MBeanServer mbeanServer;
- private final AccessControlContext acc;
-
- AuthInvocationHandler(MBeanServer server, Subject subject) {
- this.mbeanServer = server;
- if (subject == null) {
- this.acc = null;
- } else {
- if (SubjectDelegator.checkRemoveCallerContext(subject)) {
- acc = JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
- } else {
- acc = JMXSubjectDomainCombiner.getContext(subject);
- }
- }
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (acc == null) {
- return method.invoke(mbeanServer, args);
- } else {
- PrivilegedAction<Object> op = () -> {
- try {
- return method.invoke(mbeanServer, args);
- } catch (Exception ex) {
- }
- return null;
- };
- return AccessController.doPrivileged(op, acc);
- }
- }
- }
-
- /*
- This is an expiring map that removes entries after the configured time period lapses.
- This is required to re-authenticate the user after the timeout.
- */
- private class TimedMap<K,V> {
-
- private ConcurrentHashMap<K,TimeStampedValue<V>> permanentMap;
- private long timeout = Long.MAX_VALUE; // Timeout in seconds
-
- private class TimeStampedValue<T> {
- private final T value;
- private final long insertTimeStamp;
-
- TimeStampedValue(T value) {
- this.value = value;
- insertTimeStamp = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
- }
- }
-
- public TimedMap(int seconds) {
- this.timeout = seconds;
- permanentMap = new ConcurrentHashMap<>();
- }
-
- public boolean containsKey(K key) {
- return permanentMap.containsKey(key);
- }
-
- public V get(K key) {
- TimeStampedValue<V> vTimeStampedValue = permanentMap.get(key);
- long current = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
- if(current - vTimeStampedValue.insertTimeStamp > timeout) {
- permanentMap.remove(key);
- return null;
- } else {
- return vTimeStampedValue.value;
- }
- }
-
- public void put(K key, V value) {
- permanentMap.put(key, new TimeStampedValue<>(value));
- }
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/RestResource.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.http;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-
-import java.io.IOException;
-
-/**
- *
- * @author harsha
- */
-public interface RestResource extends HttpHandler {
- @Override
- public default void handle(HttpExchange exchange) throws IOException {
- HttpResponse httpResponse = HttpResponse.METHOD_NOT_ALLOWED;
- switch (exchange.getRequestMethod()) {
- case "GET":
- httpResponse = doGet(exchange);
- break;
- case "POST":
- httpResponse = doPost(exchange);
- break;
- case "PUT":
- httpResponse = doPut(exchange);
- break;
- case "DELETE":
- httpResponse = doDelete(exchange);
- break;
- case "HEAD":
- httpResponse = doHead(exchange);
- break;
- case "PATCH":
- httpResponse = doPatch(exchange);
- break;
- case "CONNET":
- httpResponse = doConnect(exchange);
- break;
- case "TRACE":
- httpResponse = doTrace(exchange);
- break;
- case "OPTIONS":
- httpResponse = doOptions(exchange);
- break;
- }
- HttpUtil.sendResponse(exchange, httpResponse);
- }
-
- public default HttpResponse doGet(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doPut(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doPost(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doDelete(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doHead(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doConnect(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doOptions(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doTrace(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-
- public default HttpResponse doPatch(HttpExchange exchange) {
- return HttpResponse.METHOD_NOT_ALLOWED;
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONArray.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.json;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * @author harsha
- */
-public class JSONArray extends ArrayList<JSONElement> implements JSONElement {
-
- private static final long serialVersionUID = -506975558678956426L;
-
- @Override
- public String toJsonString() {
- if (isEmpty()) {
- return null;
- }
- StringBuilder sbuild = new StringBuilder();
- sbuild.append("[");
- Iterator<JSONElement> itr = iterator();
- while (itr.hasNext()) {
- JSONElement val = itr.next();
- if (val != null)
- sbuild.append(val.toJsonString()).append(", ");
- else
- sbuild.append("null").append(", ");
- }
-
- sbuild.deleteCharAt(sbuild.lastIndexOf(","));
- sbuild.append("]");
- return sbuild.toString();
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONElement.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.json;
-
-/**
- * @author harsha
- */
-public interface JSONElement {
- public String toJsonString();
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONObject.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.json;
-
-import java.util.LinkedHashMap;
-
-/**
- * @author harsha
- */
-public class JSONObject extends LinkedHashMap<String, JSONElement> implements JSONElement {
-
- private static final long serialVersionUID = -9148596129640441014L;
-
- public JSONObject() {
- super();
- }
-
- public JSONObject(JSONObject jsonObject) {
- super(jsonObject);
- }
-
- public JSONElement put(String key, String value) {
- return super.put(key, new JSONPrimitive(value)); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public String toJsonString() {
- if (isEmpty()) {
- return null;
- }
-
- StringBuilder sbuild = new StringBuilder();
- sbuild.append("{");
- keySet().forEach((s) -> {
- sbuild.append("\"").append(s).append("\"").append(": ").
- append((get(s) != null) ? get(s).toJsonString() : "null").append(",");
- });
-
- sbuild.deleteCharAt(sbuild.lastIndexOf(","));
- sbuild.append("}");
- return sbuild.toString();
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/JSONPrimitive.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.json;
-
-/**
- * @author harsha
- */
-public class JSONPrimitive implements JSONElement {
-
- private final Object value;
-
- public JSONPrimitive(long i) {
- value = i;
- }
-
- public JSONPrimitive(double i) {
- value = i;
- }
-
- public JSONPrimitive(Boolean i) {
- value = i;
- }
-
- public JSONPrimitive(String s) {
- value = s;
- }
-
- public static String escape(String s) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < s.length(); i++) {
- char ch = s.charAt(i);
- if (ch == '\\') {
- if (i < s.length() - 1 && (s.charAt(i + 1) == '\\' || s.charAt(i + 1) == '"')) {
- sb.append(ch).append(s.charAt(i + 1));
- i++;
- } else {
- sb.append("\\\\");
- }
- } else if (ch == '"') {
- sb.append("\\\"");
- } else {
- sb.append(ch);
- }
- }
- return sb.toString();
- }
-
- public Object getValue() {
- return value;
- }
-
- @Override
- public String toJsonString() {
- if (value instanceof String) {
- return "\"" + escape(value.toString()) + "\"";
- }
- return value != null ? value.toString() : null;
- }
-
- @Override
- public int hashCode() {
- if (value instanceof String) {
- return ((String) value).hashCode();
- } else if (value instanceof Long) {
- return ((Long) value).hashCode();
- } else if (value instanceof Double) {
- return ((Double) value).hashCode();
- } else if (value instanceof Boolean) {
- return ((Boolean) value).hashCode();
- } else {
- return super.hashCode();
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
-
- if (!(obj instanceof JSONPrimitive)) {
- return false;
- }
-
- JSONPrimitive o = (JSONPrimitive) obj;
-
- if (value == null && o.getValue() == null) {
- return true;
- }
-
- if (value != null && o.getValue() != null) {
- if (value.getClass().equals(o.getValue().getClass())) {
- return value.equals(o.getValue());
- }
- }
- return false;
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JSONParser.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. JSONParser.java */
-package com.oracle.jmx.remote.rest.json.parser;
-
-import java.io.StringReader;
-import com.oracle.jmx.remote.rest.json.*;
-
-public class JSONParser implements JSONParserConstants {
-
- public JSONParser(String input) {
- this(new StringReader(input));
- }
-
- public JSONElement parse() throws ParseException {
- return jsonValue();
- }
-
- final public JSONElement jsonValue() throws ParseException {
- JSONElement x;
- switch (jj_nt.kind) {
- case 16:
- x = object();
- break;
- case 20:
- x = list();
- break;
- case QUOTED_STRING:
- x = string();
- break;
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- x = number();
- break;
- case BOOL_LITERAL:
- x = boolVal();
- break;
- case NULL:
- x = nullVal();
- break;
- default:
- jj_la1[0] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- {if (true) return x;}
- throw new Error("Missing return statement in function");
- }
-
- final public JSONObject object() throws ParseException {
- final JSONObject jobject = new JSONObject();
- JSONPrimitive key;
- JSONElement value;
- jj_consume_token(16);
- key = string();
- jj_consume_token(17);
- value = jsonValue();
- jobject.put((String)key.getValue(), value);
- label_1:
- while (true) {
- switch (jj_nt.kind) {
- case 18:
- ;
- break;
- default:
- jj_la1[1] = jj_gen;
- break label_1;
- }
- jj_consume_token(18);
- key = string();
- jj_consume_token(17);
- value = jsonValue();
- jobject.put((String)key.getValue(), value);
- }
- jj_consume_token(19);
- {if (true) return jobject;}
- throw new Error("Missing return statement in function");
- }
-
- final public JSONArray list() throws ParseException {
- final JSONArray jarray = new JSONArray();
- JSONElement value;
- jj_consume_token(20);
- value = jsonValue();
- jarray.add(value);
- label_2:
- while (true) {
- switch (jj_nt.kind) {
- case 18:
- ;
- break;
- default:
- jj_la1[2] = jj_gen;
- break label_2;
- }
- jj_consume_token(18);
- value = jsonValue();
- jarray.add(value);
- }
- jj_consume_token(21);
- {if (true) return jarray;}
- throw new Error("Missing return statement in function");
- }
-
- final public JSONPrimitive nullVal() throws ParseException {
- jj_consume_token(NULL);
- {if (true) return null;}
- throw new Error("Missing return statement in function");
- }
-
- final public JSONPrimitive boolVal() throws ParseException {
- jj_consume_token(BOOL_LITERAL);
- {if (true) return new JSONPrimitive(Boolean.parseBoolean(token.image));}
- throw new Error("Missing return statement in function");
- }
-
- final public JSONPrimitive number() throws ParseException {
- Token t;
- switch (jj_nt.kind) {
- case INTEGER_LITERAL:
- t = jj_consume_token(INTEGER_LITERAL);
- {if (true) return new JSONPrimitive(Long.parseLong(t.image));}
- break;
- case FLOATING_POINT_LITERAL:
- t = jj_consume_token(FLOATING_POINT_LITERAL);
- {if (true) return new JSONPrimitive(Double.parseDouble(t.image));}
- break;
- default:
- jj_la1[3] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- throw new Error("Missing return statement in function");
- }
-
- final public JSONPrimitive string() throws ParseException {
- Token t;
- t = jj_consume_token(QUOTED_STRING);
- {if (true) return new JSONPrimitive(t.image.substring(1,t.image.length()-1));}
- throw new Error("Missing return statement in function");
- }
-
- /** Generated Token Manager. */
- public JSONParserTokenManager token_source;
- JavaCharStream jj_input_stream;
- /** Current token. */
- public Token token;
- /** Next token. */
- public Token jj_nt;
- private int jj_gen;
- final private int[] jj_la1 = new int[4];
- static private int[] jj_la1_0;
- static {
- jj_la1_init_0();
- }
- private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x11e180,0x40000,0x40000,0x180,};
- }
-
- /** Constructor with InputStream. */
- public JSONParser(java.io.InputStream stream) {
- this(stream, null);
- }
- /** Constructor with InputStream and supplied encoding */
- public JSONParser(java.io.InputStream stream, String encoding) {
- try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
- token_source = new JSONParserTokenManager(jj_input_stream);
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- /** Reinitialise. */
- public void ReInit(java.io.InputStream stream) {
- ReInit(stream, null);
- }
- /** Reinitialise. */
- public void ReInit(java.io.InputStream stream, String encoding) {
- try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
- token_source.ReInit(jj_input_stream);
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- /** Constructor. */
- public JSONParser(java.io.Reader stream) {
- jj_input_stream = new JavaCharStream(stream, 1, 1);
- token_source = new JSONParserTokenManager(jj_input_stream);
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- /** Reinitialise. */
- public void ReInit(java.io.Reader stream) {
- jj_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(jj_input_stream);
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- /** Constructor with generated Token Manager. */
- public JSONParser(JSONParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- /** Reinitialise. */
- public void ReInit(JSONParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- token.next = jj_nt = token_source.getNextToken();
- jj_gen = 0;
- for (int i = 0; i < 4; i++) jj_la1[i] = -1;
- }
-
- private Token jj_consume_token(int kind) throws ParseException {
- Token oldToken = token;
- if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
- else jj_nt = jj_nt.next = token_source.getNextToken();
- if (token.kind == kind) {
- jj_gen++;
- return token;
- }
- jj_nt = token;
- token = oldToken;
- jj_kind = kind;
- throw generateParseException();
- }
-
-
-/** Get the next Token. */
- final public Token getNextToken() {
- if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
- else jj_nt = jj_nt.next = token_source.getNextToken();
- jj_gen++;
- return token;
- }
-
-/** Get the specific Token. */
- final public Token getToken(int index) {
- Token t = token;
- for (int i = 0; i < index; i++) {
- if (t.next != null) t = t.next;
- else t = t.next = token_source.getNextToken();
- }
- return t;
- }
-
- private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
- private int[] jj_expentry;
- private int jj_kind = -1;
-
- /** Generate ParseException. */
- public ParseException generateParseException() {
- jj_expentries.clear();
- boolean[] la1tokens = new boolean[22];
- if (jj_kind >= 0) {
- la1tokens[jj_kind] = true;
- jj_kind = -1;
- }
- for (int i = 0; i < 4; i++) {
- if (jj_la1[i] == jj_gen) {
- for (int j = 0; j < 32; j++) {
- if ((jj_la1_0[i] & (1<<j)) != 0) {
- la1tokens[j] = true;
- }
- }
- }
- }
- for (int i = 0; i < 22; i++) {
- if (la1tokens[i]) {
- jj_expentry = new int[1];
- jj_expentry[0] = i;
- jj_expentries.add(jj_expentry);
- }
- }
- int[][] exptokseq = new int[jj_expentries.size()][];
- for (int i = 0; i < jj_expentries.size(); i++) {
- exptokseq[i] = jj_expentries.get(i);
- }
- return new ParseException(token, exptokseq, tokenImage);
- }
-
- /** Enable tracing. */
- final public void enable_tracing() {
- }
-
- /** Disable tracing. */
- final public void disable_tracing() {
- }
-
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JSONParserConstants.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. JSONParserConstants.java */
-package com.oracle.jmx.remote.rest.json.parser;
-
-
-/**
- * Token literal values and constants.
- * Generated by org.javacc.parser.OtherFilesGen#start()
- */
-public interface JSONParserConstants {
-
- /** End of File. */
- int EOF = 0;
- /** RegularExpression Id. */
- int INTEGER_LITERAL = 7;
- /** RegularExpression Id. */
- int FLOATING_POINT_LITERAL = 8;
- /** RegularExpression Id. */
- int FRAC = 9;
- /** RegularExpression Id. */
- int EXPONENT = 10;
- /** RegularExpression Id. */
- int DIGITS = 11;
- /** RegularExpression Id. */
- int DIGIT = 12;
- /** RegularExpression Id. */
- int QUOTED_STRING = 13;
- /** RegularExpression Id. */
- int BOOL_LITERAL = 14;
- /** RegularExpression Id. */
- int NULL = 15;
-
- /** Lexical state. */
- int DEFAULT = 0;
-
- /** Literal token values. */
- String[] tokenImage = {
- "<EOF>",
- "\" \"",
- "\"\\b\"",
- "\"\\t\"",
- "\"\\n\"",
- "\"\\r\"",
- "\"\\f\"",
- "<INTEGER_LITERAL>",
- "<FLOATING_POINT_LITERAL>",
- "<FRAC>",
- "<EXPONENT>",
- "<DIGITS>",
- "<DIGIT>",
- "<QUOTED_STRING>",
- "<BOOL_LITERAL>",
- "\"null\"",
- "\"{\"",
- "\":\"",
- "\",\"",
- "\"}\"",
- "\"[\"",
- "\"]\"",
- };
-
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JSONParserTokenManager.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,540 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. JSONParserTokenManager.java */
-package com.oracle.jmx.remote.rest.json.parser;
-import java.io.StringReader;
-import com.oracle.jmx.remote.rest.json.*;
-
-/** Token Manager. */
-public class JSONParserTokenManager implements JSONParserConstants
-{
-
- /** Debug output. */
- public java.io.PrintStream debugStream = System.out;
- /** Set debug output. */
- public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_0(int pos, long active0)
-{
- switch (pos)
- {
- default :
- return -1;
- }
-}
-private final int jjStartNfa_0(int pos, long active0)
-{
- return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-private int jjStopAtPos(int pos, int kind)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- return pos + 1;
-}
-private int jjMoveStringLiteralDfa0_0()
-{
- switch(curChar)
- {
- case 44:
- return jjStopAtPos(0, 18);
- case 58:
- return jjStopAtPos(0, 17);
- case 91:
- return jjStopAtPos(0, 20);
- case 93:
- return jjStopAtPos(0, 21);
- case 78:
- case 110:
- return jjMoveStringLiteralDfa1_0(0x8000L);
- case 123:
- return jjStopAtPos(0, 16);
- case 125:
- return jjStopAtPos(0, 19);
- default :
- return jjMoveNfa_0(0, 0);
- }
-}
-private int jjMoveStringLiteralDfa1_0(long active0)
-{
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(0, active0);
- return 1;
- }
- switch(curChar)
- {
- case 85:
- case 117:
- return jjMoveStringLiteralDfa2_0(active0, 0x8000L);
- default :
- break;
- }
- return jjStartNfa_0(0, active0);
-}
-private int jjMoveStringLiteralDfa2_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(0, old0);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(1, active0);
- return 2;
- }
- switch(curChar)
- {
- case 76:
- case 108:
- return jjMoveStringLiteralDfa3_0(active0, 0x8000L);
- default :
- break;
- }
- return jjStartNfa_0(1, active0);
-}
-private int jjMoveStringLiteralDfa3_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(1, old0);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(2, active0);
- return 3;
- }
- switch(curChar)
- {
- case 76:
- case 108:
- if ((active0 & 0x8000L) != 0L)
- return jjStopAtPos(3, 15);
- break;
- default :
- break;
- }
- return jjStartNfa_0(2, active0);
-}
-static final long[] jjbitVec0 = {
- 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec2 = {
- 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-private int jjMoveNfa_0(int startState, int curPos)
-{
- int startsAt = 0;
- jjnewStateCnt = 29;
- int i = 1;
- jjstateSet[0] = startState;
- int kind = 0x7fffffff;
- for (;;)
- {
- if (++jjround == 0x7fffffff)
- ReInitRounds();
- if (curChar < 64)
- {
- long l = 1L << curChar;
- do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if ((0x3ff000000000000L & l) != 0L)
- {
- if (kind > 7)
- kind = 7;
- jjCheckNAddStates(0, 6);
- }
- else if (curChar == 45)
- jjCheckNAddStates(7, 10);
- else if (curChar == 34)
- jjCheckNAddStates(11, 13);
- break;
- case 1:
- if ((0xfffffffbffffffffL & l) != 0L)
- jjCheckNAddStates(11, 13);
- break;
- case 3:
- if (curChar == 34)
- jjCheckNAddStates(11, 13);
- break;
- case 4:
- if (curChar == 34 && kind > 13)
- kind = 13;
- break;
- case 13:
- if (curChar == 45)
- jjCheckNAddStates(7, 10);
- break;
- case 14:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 7)
- kind = 7;
- jjCheckNAdd(14);
- break;
- case 15:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(15, 16);
- break;
- case 16:
- if (curChar == 46)
- jjCheckNAdd(17);
- break;
- case 17:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAdd(17);
- break;
- case 18:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(18, 19);
- break;
- case 20:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(21);
- break;
- case 21:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAdd(21);
- break;
- case 22:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(22, 23);
- break;
- case 23:
- if (curChar == 46)
- jjCheckNAdd(24);
- break;
- case 24:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(24, 25);
- break;
- case 26:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(27);
- break;
- case 27:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAdd(27);
- break;
- case 28:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 7)
- kind = 7;
- jjCheckNAddStates(0, 6);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else if (curChar < 128)
- {
- long l = 1L << (curChar & 077);
- do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if ((0x4000000040L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 11;
- else if ((0x10000000100000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 7;
- break;
- case 1:
- if ((0xffffffffefffffffL & l) != 0L)
- jjCheckNAddStates(11, 13);
- break;
- case 2:
- if (curChar == 92)
- jjstateSet[jjnewStateCnt++] = 3;
- break;
- case 3:
- if ((0x14404410144044L & l) != 0L)
- jjCheckNAddStates(11, 13);
- break;
- case 5:
- if ((0x2000000020L & l) != 0L && kind > 14)
- kind = 14;
- break;
- case 6:
- if ((0x20000000200000L & l) != 0L)
- jjCheckNAdd(5);
- break;
- case 7:
- if ((0x4000000040000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 6;
- break;
- case 8:
- if ((0x10000000100000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 7;
- break;
- case 9:
- if ((0x8000000080000L & l) != 0L)
- jjCheckNAdd(5);
- break;
- case 10:
- if ((0x100000001000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 9;
- break;
- case 11:
- if ((0x200000002L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 10;
- break;
- case 12:
- if ((0x4000000040L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 11;
- break;
- case 19:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(14, 15);
- break;
- case 25:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(16, 17);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else
- {
- int hiByte = (curChar >> 8);
- int i1 = hiByte >> 6;
- long l1 = 1L << (hiByte & 077);
- int i2 = (curChar & 0xff) >> 6;
- long l2 = 1L << (curChar & 077);
- do
- {
- switch(jjstateSet[--i])
- {
- case 1:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(11, 13);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- if (kind != 0x7fffffff)
- {
- jjmatchedKind = kind;
- jjmatchedPos = curPos;
- kind = 0x7fffffff;
- }
- ++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 29 - (jjnewStateCnt = startsAt)))
- return curPos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return curPos; }
- }
-}
-static final int[] jjnextStates = {
- 14, 15, 16, 18, 19, 22, 23, 14, 15, 18, 22, 1, 2, 4, 20, 21,
- 26, 27,
-};
-private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((jjbitVec2[i2] & l2) != 0L);
- default :
- if ((jjbitVec0[i1] & l1) != 0L)
- return true;
- return false;
- }
-}
-
-/** Token literal values. */
-public static final String[] jjstrLiteralImages = {
-"", null, null, null, null, null, null, null, null, null, null, null, null,
-null, null, null, "\173", "\72", "\54", "\175", "\133", "\135", };
-
-/** Lexer state names. */
-public static final String[] lexStateNames = {
- "DEFAULT",
-};
-static final long[] jjtoToken = {
- 0x3fe181L,
-};
-static final long[] jjtoSkip = {
- 0x7eL,
-};
-protected JavaCharStream input_stream;
-private final int[] jjrounds = new int[29];
-private final int[] jjstateSet = new int[58];
-protected char curChar;
-/** Constructor. */
-public JSONParserTokenManager(JavaCharStream stream){
- if (JavaCharStream.staticFlag)
- throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
- input_stream = stream;
-}
-
-/** Constructor. */
-public JSONParserTokenManager(JavaCharStream stream, int lexState){
- this(stream);
- SwitchTo(lexState);
-}
-
-/** Reinitialise parser. */
-public void ReInit(JavaCharStream stream)
-{
- jjmatchedPos = jjnewStateCnt = 0;
- curLexState = defaultLexState;
- input_stream = stream;
- ReInitRounds();
-}
-private void ReInitRounds()
-{
- int i;
- jjround = 0x80000001;
- for (i = 29; i-- > 0;)
- jjrounds[i] = 0x80000000;
-}
-
-/** Reinitialise parser. */
-public void ReInit(JavaCharStream stream, int lexState)
-{
- ReInit(stream);
- SwitchTo(lexState);
-}
-
-/** Switch to specified lex state. */
-public void SwitchTo(int lexState)
-{
- if (lexState >= 1 || lexState < 0)
- throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
- else
- curLexState = lexState;
-}
-
-protected Token jjFillToken()
-{
- final Token t;
- final String curTokenImage;
- final int beginLine;
- final int endLine;
- final int beginColumn;
- final int endColumn;
- String im = jjstrLiteralImages[jjmatchedKind];
- curTokenImage = (im == null) ? input_stream.GetImage() : im;
- beginLine = input_stream.getBeginLine();
- beginColumn = input_stream.getBeginColumn();
- endLine = input_stream.getEndLine();
- endColumn = input_stream.getEndColumn();
- t = Token.newToken(jjmatchedKind, curTokenImage);
-
- t.beginLine = beginLine;
- t.endLine = endLine;
- t.beginColumn = beginColumn;
- t.endColumn = endColumn;
-
- return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-/** Get the next Token. */
-public Token getNextToken()
-{
- Token matchedToken;
- int curPos = 0;
-
- EOFLoop :
- for (;;)
- {
- try
- {
- curChar = input_stream.BeginToken();
- }
- catch(java.io.IOException e)
- {
- jjmatchedKind = 0;
- matchedToken = jjFillToken();
- return matchedToken;
- }
-
- try { input_stream.backup(0);
- while (curChar <= 32 && (0x100003700L & (1L << curChar)) != 0L)
- curChar = input_stream.BeginToken();
- }
- catch (java.io.IOException e1) { continue EOFLoop; }
- jjmatchedKind = 0x7fffffff;
- jjmatchedPos = 0;
- curPos = jjMoveStringLiteralDfa0_0();
- if (jjmatchedKind != 0x7fffffff)
- {
- if (jjmatchedPos + 1 < curPos)
- input_stream.backup(curPos - jjmatchedPos - 1);
- if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
- {
- matchedToken = jjFillToken();
- return matchedToken;
- }
- else
- {
- continue EOFLoop;
- }
- }
- int error_line = input_stream.getEndLine();
- int error_column = input_stream.getEndColumn();
- String error_after = null;
- boolean EOFSeen = false;
- try { input_stream.readChar(); input_stream.backup(1); }
- catch (java.io.IOException e1) {
- EOFSeen = true;
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- if (curChar == '\n' || curChar == '\r') {
- error_line++;
- error_column = 0;
- }
- else
- error_column++;
- }
- if (!EOFSeen) {
- input_stream.backup(1);
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- }
- throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
- }
-}
-
-private void jjCheckNAdd(int state)
-{
- if (jjrounds[state] != jjround)
- {
- jjstateSet[jjnewStateCnt++] = state;
- jjrounds[state] = jjround;
- }
-}
-private void jjAddStates(int start, int end)
-{
- do {
- jjstateSet[jjnewStateCnt++] = jjnextStates[start];
- } while (start++ != end);
-}
-private void jjCheckNAddTwoStates(int state1, int state2)
-{
- jjCheckNAdd(state1);
- jjCheckNAdd(state2);
-}
-
-private void jjCheckNAddStates(int start, int end)
-{
- do {
- jjCheckNAdd(jjnextStates[start]);
- } while (start++ != end);
-}
-
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JavaCharStream.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 5.0 */
-/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
-package com.oracle.jmx.remote.rest.json.parser;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (with java-like unicode escape processing).
- */
-
-public
-class JavaCharStream
-{
- /** Whether parser is static. */
- public static final boolean staticFlag = false;
-
- static final int hexval(char c) throws java.io.IOException {
- switch(c)
- {
- case '0' :
- return 0;
- case '1' :
- return 1;
- case '2' :
- return 2;
- case '3' :
- return 3;
- case '4' :
- return 4;
- case '5' :
- return 5;
- case '6' :
- return 6;
- case '7' :
- return 7;
- case '8' :
- return 8;
- case '9' :
- return 9;
-
- case 'a' :
- case 'A' :
- return 10;
- case 'b' :
- case 'B' :
- return 11;
- case 'c' :
- case 'C' :
- return 12;
- case 'd' :
- case 'D' :
- return 13;
- case 'e' :
- case 'E' :
- return 14;
- case 'f' :
- case 'F' :
- return 15;
- }
-
- throw new java.io.IOException(); // Should never come here
- }
-
-/** Position in buffer. */
- public int bufpos = -1;
- int bufsize;
- int available;
- int tokenBegin;
- protected int bufline[];
- protected int bufcolumn[];
-
- protected int column = 0;
- protected int line = 1;
-
- protected boolean prevCharIsCR = false;
- protected boolean prevCharIsLF = false;
-
- protected java.io.Reader inputStream;
-
- protected char[] nextCharBuf;
- protected char[] buffer;
- protected int maxNextCharInd = 0;
- protected int nextCharInd = -1;
- protected int inBuf = 0;
- protected int tabSize = 8;
-
- protected void setTabSize(int i) { tabSize = i; }
- protected int getTabSize(int i) { return tabSize; }
-
- protected void ExpandBuff(boolean wrapAround)
- {
- char[] newbuffer = new char[bufsize + 2048];
- int newbufline[] = new int[bufsize + 2048];
- int newbufcolumn[] = new int[bufsize + 2048];
-
- try
- {
- if (wrapAround)
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
- bufcolumn = newbufcolumn;
-
- bufpos += (bufsize - tokenBegin);
- }
- else
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- bufcolumn = newbufcolumn;
-
- bufpos -= tokenBegin;
- }
- }
- catch (Throwable t)
- {
- throw new Error(t.getMessage());
- }
-
- available = (bufsize += 2048);
- tokenBegin = 0;
- }
-
- protected void FillBuff() throws java.io.IOException
- {
- int i;
- if (maxNextCharInd == 4096)
- maxNextCharInd = nextCharInd = 0;
-
- try {
- if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
- 4096 - maxNextCharInd)) == -1)
- {
- inputStream.close();
- throw new java.io.IOException();
- }
- else
- maxNextCharInd += i;
- return;
- }
- catch(java.io.IOException e) {
- if (bufpos != 0)
- {
- --bufpos;
- backup(0);
- }
- else
- {
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
- throw e;
- }
- }
-
- protected char ReadByte() throws java.io.IOException
- {
- if (++nextCharInd >= maxNextCharInd)
- FillBuff();
-
- return nextCharBuf[nextCharInd];
- }
-
-/** @return starting character for token. */
- public char BeginToken() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
-
- if (++bufpos == bufsize)
- bufpos = 0;
-
- tokenBegin = bufpos;
- return buffer[bufpos];
- }
-
- tokenBegin = 0;
- bufpos = -1;
-
- return readChar();
- }
-
- protected void AdjustBuffSize()
- {
- if (available == bufsize)
- {
- if (tokenBegin > 2048)
- {
- bufpos = 0;
- available = tokenBegin;
- }
- else
- ExpandBuff(false);
- }
- else if (available > tokenBegin)
- available = bufsize;
- else if ((tokenBegin - available) < 2048)
- ExpandBuff(true);
- else
- available = tokenBegin;
- }
-
- protected void UpdateLineColumn(char c)
- {
- column++;
-
- if (prevCharIsLF)
- {
- prevCharIsLF = false;
- line += (column = 1);
- }
- else if (prevCharIsCR)
- {
- prevCharIsCR = false;
- if (c == '\n')
- {
- prevCharIsLF = true;
- }
- else
- line += (column = 1);
- }
-
- switch (c)
- {
- case '\r' :
- prevCharIsCR = true;
- break;
- case '\n' :
- prevCharIsLF = true;
- break;
- case '\t' :
- column--;
- column += (tabSize - (column % tabSize));
- break;
- default :
- break;
- }
-
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
-
-/** Read a character. */
- public char readChar() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
-
- if (++bufpos == bufsize)
- bufpos = 0;
-
- return buffer[bufpos];
- }
-
- char c;
-
- if (++bufpos == available)
- AdjustBuffSize();
-
- if ((buffer[bufpos] = c = ReadByte()) == '\\')
- {
- UpdateLineColumn(c);
-
- int backSlashCnt = 1;
-
- for (;;) // Read all the backslashes
- {
- if (++bufpos == available)
- AdjustBuffSize();
-
- try
- {
- if ((buffer[bufpos] = c = ReadByte()) != '\\')
- {
- UpdateLineColumn(c);
- // found a non-backslash char.
- if ((c == 'u') && ((backSlashCnt & 1) == 1))
- {
- if (--bufpos < 0)
- bufpos = bufsize - 1;
-
- break;
- }
-
- backup(backSlashCnt);
- return '\\';
- }
- }
- catch(java.io.IOException e)
- {
- // We are returning one backslash so we should only backup (count-1)
- if (backSlashCnt > 1)
- backup(backSlashCnt-1);
-
- return '\\';
- }
-
- UpdateLineColumn(c);
- backSlashCnt++;
- }
-
- // Here, we have seen an odd number of backslash's followed by a 'u'
- try
- {
- while ((c = ReadByte()) == 'u')
- ++column;
-
- buffer[bufpos] = c = (char)(hexval(c) << 12 |
- hexval(ReadByte()) << 8 |
- hexval(ReadByte()) << 4 |
- hexval(ReadByte()));
-
- column += 4;
- }
- catch(java.io.IOException e)
- {
- throw new Error("Invalid escape character at line " + line +
- " column " + column + ".");
- }
-
- if (backSlashCnt == 1)
- return c;
- else
- {
- backup(backSlashCnt - 1);
- return '\\';
- }
- }
- else
- {
- UpdateLineColumn(c);
- return c;
- }
- }
-
- @Deprecated
- /**
- * @deprecated
- * @see #getEndColumn
- */
- public int getColumn() {
- return bufcolumn[bufpos];
- }
-
- @Deprecated
- /**
- * @deprecated
- * @see #getEndLine
- */
- public int getLine() {
- return bufline[bufpos];
- }
-
-/** Get end column. */
- public int getEndColumn() {
- return bufcolumn[bufpos];
- }
-
-/** Get end line. */
- public int getEndLine() {
- return bufline[bufpos];
- }
-
-/** @return column of token start */
- public int getBeginColumn() {
- return bufcolumn[tokenBegin];
- }
-
-/** @return line number of token start */
- public int getBeginLine() {
- return bufline[tokenBegin];
- }
-
-/** Retreat. */
- public void backup(int amount) {
-
- inBuf += amount;
- if ((bufpos -= amount) < 0)
- bufpos += bufsize;
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.Reader dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new char[4096];
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.Reader dstream,
- int startline, int startcolumn)
- {
- this(dstream, startline, startcolumn, 4096);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.Reader dstream)
- {
- this(dstream, 1, 1, 4096);
- }
-/** Reinitialise. */
- public void ReInit(java.io.Reader dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- if (buffer == null || buffersize != buffer.length)
- {
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new char[4096];
- }
- prevCharIsLF = prevCharIsCR = false;
- tokenBegin = inBuf = maxNextCharInd = 0;
- nextCharInd = bufpos = -1;
- }
-
-/** Reinitialise. */
- public void ReInit(java.io.Reader dstream,
- int startline, int startcolumn)
- {
- ReInit(dstream, startline, startcolumn, 4096);
- }
-
-/** Reinitialise. */
- public void ReInit(java.io.Reader dstream)
- {
- ReInit(dstream, 1, 1, 4096);
- }
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
- int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
- {
- this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream, int startline,
- int startcolumn, int buffersize)
- {
- this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
- int startcolumn) throws java.io.UnsupportedEncodingException
- {
- this(dstream, encoding, startline, startcolumn, 4096);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream, int startline,
- int startcolumn)
- {
- this(dstream, startline, startcolumn, 4096);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
- {
- this(dstream, encoding, 1, 1, 4096);
- }
-
-/** Constructor. */
- public JavaCharStream(java.io.InputStream dstream)
- {
- this(dstream, 1, 1, 4096);
- }
-
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream, String encoding, int startline,
- int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
- {
- ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
- }
-
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream, int startline,
- int startcolumn, int buffersize)
- {
- ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
- }
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream, String encoding, int startline,
- int startcolumn) throws java.io.UnsupportedEncodingException
- {
- ReInit(dstream, encoding, startline, startcolumn, 4096);
- }
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream, int startline,
- int startcolumn)
- {
- ReInit(dstream, startline, startcolumn, 4096);
- }
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
- {
- ReInit(dstream, encoding, 1, 1, 4096);
- }
-
-/** Reinitialise. */
- public void ReInit(java.io.InputStream dstream)
- {
- ReInit(dstream, 1, 1, 4096);
- }
-
- /** @return token image as String */
- public String GetImage()
- {
- if (bufpos >= tokenBegin)
- return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
- else
- return new String(buffer, tokenBegin, bufsize - tokenBegin) +
- new String(buffer, 0, bufpos + 1);
- }
-
- /** @return suffix */
- public char[] GetSuffix(int len)
- {
- char[] ret = new char[len];
-
- if ((bufpos + 1) >= len)
- System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
- else
- {
- System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
- len - bufpos - 1);
- System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
- }
-
- return ret;
- }
-
- /** Set buffers back to null when finished. */
- public void Done()
- {
- nextCharBuf = null;
- buffer = null;
- bufline = null;
- bufcolumn = null;
- }
-
- /**
- * Method to adjust line and column numbers for the start of a token.
- */
- public void adjustBeginLineColumn(int newLine, int newCol)
- {
- int start = tokenBegin;
- int len;
-
- if (bufpos >= tokenBegin)
- {
- len = bufpos - tokenBegin + inBuf + 1;
- }
- else
- {
- len = bufsize - tokenBegin + bufpos + 1 + inBuf;
- }
-
- int i = 0, j = 0, k = 0;
- int nextColDiff = 0, columnDiff = 0;
-
- while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
- {
- bufline[j] = newLine;
- nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
- bufcolumn[j] = newCol + columnDiff;
- columnDiff = nextColDiff;
- i++;
- }
-
- if (i < len)
- {
- bufline[j] = newLine++;
- bufcolumn[j] = newCol + columnDiff;
-
- while (i++ < len)
- {
- if (bufline[j = start % bufsize] != bufline[++start % bufsize])
- bufline[j] = newLine++;
- else
- bufline[j] = newLine;
- }
- }
-
- line = bufline[j];
- column = bufcolumn[j];
- }
-
-}
-/* JavaCC - OriginalChecksum=3b79d8fd3ca02005c805e406bf89cd35 (do not edit this line) */
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/JsonParser.jj Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
- /*
- * This is the JavaCC grammar file for a JSON parser. The productions are
- * based on syntax diagrams as specified at json.org
- * Every type of JSON is represent by a JSONElement. JSON Objects are mapped to
- * by LinkedHashMap via JSONObject. JSON Arrays are mapped to ArrayList via JSONArray
- * String, Number, Boolean and null are wrapped into a JSONPrimitive.
- * Control characters inside a string (JSONPrimitive(String)) are not escaped and are passed through
- * to ouput JSON string generated by toJsonString method of JSONElement.
- * Inside a String, only backslash ('\') and double quote ('"') characters
- * are escaped by a backslash, if they are not already escaped.
- * Applications consuming json string generated by JSON* objects must take care
- * to escape control characters within strings by prefixing with a backslash character,
- * if not already escaped.
- */
-options {
- STATIC=false;
- ERROR_REPORTING=true;
- JAVA_UNICODE_ESCAPE=true;
- UNICODE_INPUT=true;
- IGNORE_CASE=true;
- CACHE_TOKENS=true;
-// DEBUG_PARSER=true;
-// DEBUG_LOOKAHEAD=true;
-// DEBUG_TOKEN_MANAGER=true;
-}
-
-PARSER_BEGIN(JSONParser)
-
-package com.oracle.jmx.remote.rest.json.parser;
-
-import java.io.StringReader;
-import com.oracle.jmx.remote.rest.json.*;
-
-public class JSONParser {
-
- public JSONParser(String input) {
- this(new StringReader(input));
- }
-
- public JSONElement parse() throws ParseException {
- return jsonValue();
- }
-}
-
-PARSER_END(JSONParser)
-
-SKIP: {
- " " | "\b" | "\t" | "\n" | "\r" | "\f"
-}
-
-TOKEN:{
- <INTEGER_LITERAL : (["-"])? (<DIGITS>)>
-| < FLOATING_POINT_LITERAL:
- <INTEGER_LITERAL> <FRAC>
-| <INTEGER_LITERAL> <EXPONENT>
-| <INTEGER_LITERAL> <FRAC> <EXPONENT>
- >
-| < #FRAC: "." <DIGITS>>
-| < #EXPONENT: ["e","E"] (["+","-"])? <DIGITS> >
-| < #DIGITS : (<DIGIT>)+>
-| < #DIGIT: ["0"-"9"]>
-| <QUOTED_STRING: "\"" ((~["\"","\\"]) | ("\\" ( ["n","t","b","r","f","\\","\""])))* "\"">
-| <BOOL_LITERAL : "true" | "false">
-| <NULL: "null">
-}
-
-JSONElement jsonValue() : {
- JSONElement x;
-}{
- ( x = object()
- | x = list()
- | x = string()
- | x = number()
- | x = boolVal()
- | x = nullVal()
- )
- { return x; }
-}
-
-JSONObject object() : {
- final JSONObject jobject = new JSONObject();
- JSONPrimitive key;
- JSONElement value;
-}{
- "{"
- (key = string())
- ":"
- value = jsonValue()
- { jobject.put((String)key.getValue(), value);}
- (
- ","
- (key = string())
- ":"
- value = jsonValue()
- { jobject.put((String)key.getValue(), value);}
- )*
- "}"
- { return jobject; }
-}
-
-JSONArray list() : {
- final JSONArray jarray = new JSONArray();
- JSONElement value;
-}{
- "["
- value = jsonValue()
- { jarray.add(value);}
- (
- ","
- value = jsonValue()
- { jarray.add(value); }
- )*
- "]"
-
- { return jarray; }
-}
-
-JSONPrimitive nullVal(): {} {
- <NULL>
- { return null; }
-}
-
-JSONPrimitive boolVal(): {}
-{
- <BOOL_LITERAL>
- {return new JSONPrimitive(Boolean.parseBoolean(token.image));}
-}
-
-JSONPrimitive number(): {
- Token t;
-}{
- (t = <INTEGER_LITERAL> { return new JSONPrimitive(Long.parseLong(t.image));})
- | (t = <FLOATING_POINT_LITERAL> { return new JSONPrimitive(Double.parseDouble(t.image));})
-}
-
-JSONPrimitive string() : {
- Token t;
-}{
- (t = <QUOTED_STRING>)
- { return new JSONPrimitive(t.image.substring(1,t.image.length()-1)); }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/ParseException.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
-/* JavaCCOptions:KEEP_LINE_COL=null */
-package com.oracle.jmx.remote.rest.json.parser;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
- /**
- * The version identifier for this Serializable class.
- * Increment only if the <i>serialized</i> form of the
- * class changes.
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * This constructor is used by the method "generateParseException"
- * in the generated parser. Calling this constructor generates
- * a new object of this type with the fields "currentToken",
- * "expectedTokenSequences", and "tokenImage" set.
- */
- public ParseException(Token currentTokenVal,
- int[][] expectedTokenSequencesVal,
- String[] tokenImageVal
- )
- {
- super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
- currentToken = currentTokenVal;
- expectedTokenSequences = expectedTokenSequencesVal;
- tokenImage = tokenImageVal;
- }
-
- /**
- * The following constructors are for use by you for whatever
- * purpose you can think of. Constructing the exception in this
- * manner makes the exception behave in the normal way - i.e., as
- * documented in the class "Throwable". The fields "errorToken",
- * "expectedTokenSequences", and "tokenImage" do not contain
- * relevant information. The JavaCC generated code does not use
- * these constructors.
- */
-
- public ParseException() {
- super();
- }
-
- /** Constructor with message. */
- public ParseException(String message) {
- super(message);
- }
-
-
- /**
- * This is the last token that has been consumed successfully. If
- * this object has been created due to a parse error, the token
- * followng this token will (therefore) be the first error token.
- */
- public Token currentToken;
-
- /**
- * Each entry in this array is an array of integers. Each array
- * of integers represents a sequence of tokens (by their ordinal
- * values) that is expected at this point of the parse.
- */
- public int[][] expectedTokenSequences;
-
- /**
- * This is a reference to the "tokenImage" array of the generated
- * parser within which the parse error occurred. This array is
- * defined in the generated ...Constants interface.
- */
- public String[] tokenImage;
-
- /**
- * It uses "currentToken" and "expectedTokenSequences" to generate a parse
- * error message and returns it. If this object has been created
- * due to a parse error, and you do not catch it (it gets thrown
- * from the parser) the correct error message
- * gets displayed.
- */
- private static String initialise(Token currentToken,
- int[][] expectedTokenSequences,
- String[] tokenImage) {
- String eol = System.getProperty("line.separator", "\n");
- StringBuffer expected = new StringBuffer();
- int maxSize = 0;
- for (int i = 0; i < expectedTokenSequences.length; i++) {
- if (maxSize < expectedTokenSequences[i].length) {
- maxSize = expectedTokenSequences[i].length;
- }
- for (int j = 0; j < expectedTokenSequences[i].length; j++) {
- expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
- }
- if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
- expected.append("...");
- }
- expected.append(eol).append(" ");
- }
- String retval = "Encountered \"";
- Token tok = currentToken.next;
- for (int i = 0; i < maxSize; i++) {
- if (i != 0) retval += " ";
- if (tok.kind == 0) {
- retval += tokenImage[0];
- break;
- }
- retval += " " + tokenImage[tok.kind];
- retval += " \"";
- retval += add_escapes(tok.image);
- retval += " \"";
- tok = tok.next;
- }
- retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
- retval += "." + eol;
- if (expectedTokenSequences.length == 1) {
- retval += "Was expecting:" + eol + " ";
- } else {
- retval += "Was expecting one of:" + eol + " ";
- }
- retval += expected.toString();
- return retval;
- }
-
- /**
- * The end of line string for this machine.
- */
- protected String eol = System.getProperty("line.separator", "\n");
-
- /**
- * Used to convert raw characters to their escaped version
- * when these raw version cannot be used as part of an ASCII
- * string literal.
- */
- static String add_escapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4, s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
-}
-/* JavaCC - OriginalChecksum=90e796a5f303517657c1e544869a38af (do not edit this line) */
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/Token.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
-/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
-package com.oracle.jmx.remote.rest.json.parser;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token implements java.io.Serializable {
-
- /**
- * The version identifier for this Serializable class.
- * Increment only if the <i>serialized</i> form of the
- * class changes.
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * An integer that describes the kind of this token. This numbering
- * system is determined by JavaCCParser, and a table of these numbers is
- * stored in the file ...Constants.java.
- */
- public int kind;
-
- /** The line number of the first character of this Token. */
- public int beginLine;
- /** The column number of the first character of this Token. */
- public int beginColumn;
- /** The line number of the last character of this Token. */
- public int endLine;
- /** The column number of the last character of this Token. */
- public int endColumn;
-
- /**
- * The string image of the token.
- */
- public String image;
-
- /**
- * A reference to the next regular (non-special) token from the input
- * stream. If this is the last token from the input stream, or if the
- * token manager has not read tokens beyond this one, this field is
- * set to null. This is true only if this token is also a regular
- * token. Otherwise, see below for a description of the contents of
- * this field.
- */
- public Token next;
-
- /**
- * This field is used to access special tokens that occur prior to this
- * token, but after the immediately preceding regular (non-special) token.
- * If there are no such special tokens, this field is set to null.
- * When there are more than one such special token, this field refers
- * to the last of these special tokens, which in turn refers to the next
- * previous special token through its specialToken field, and so on
- * until the first special token (whose specialToken field is null).
- * The next fields of special tokens refer to other special tokens that
- * immediately follow it (without an intervening regular token). If there
- * is no such token, this field is null.
- */
- public Token specialToken;
-
- /**
- * An optional attribute value of the Token.
- * Tokens which are not used as syntactic sugar will often contain
- * meaningful values that will be used later on by the compiler or
- * interpreter. This attribute value is often different from the image.
- * Any subclass of Token that actually wants to return a non-null value can
- * override this method as appropriate.
- */
- public Object getValue() {
- return null;
- }
-
- /**
- * No-argument constructor
- */
- public Token() {}
-
- /**
- * Constructs a new token for the specified Image.
- */
- public Token(int kind)
- {
- this(kind, null);
- }
-
- /**
- * Constructs a new token for the specified Image and Kind.
- */
- public Token(int kind, String image)
- {
- this.kind = kind;
- this.image = image;
- }
-
- /**
- * Returns the image.
- */
- public String toString()
- {
- return image;
- }
-
- /**
- * Returns a new Token object, by default. However, if you want, you
- * can create and return subclass objects based on the value of ofKind.
- * Simply add the cases to the switch for all those special cases.
- * For example, if you have a subclass of Token called IDToken that
- * you want to create if ofKind is ID, simply add something like :
- *
- * case MyParserConstants.ID : return new IDToken(ofKind, image);
- *
- * to the following switch statement. Then you can cast matchedToken
- * variable to the appropriate type and use sit in your lexical actions.
- */
- public static Token newToken(int ofKind, String image)
- {
- switch(ofKind)
- {
- default : return new Token(ofKind, image);
- }
- }
-
- public static Token newToken(int ofKind)
- {
- return newToken(ofKind, null);
- }
-
-}
-/* JavaCC - OriginalChecksum=c043d4e4f754c76e793a50373160a703 (do not edit this line) */
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/json/parser/TokenMgrError.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
-/* JavaCCOptions: */
-package com.oracle.jmx.remote.rest.json.parser;
-
-/** Token Manager Error. */
-public class TokenMgrError extends Error
-{
-
- /**
- * The version identifier for this Serializable class.
- * Increment only if the <i>serialized</i> form of the
- * class changes.
- */
- private static final long serialVersionUID = 1L;
-
- /*
- * Ordinals for various reasons why an Error of this type can be thrown.
- */
-
- /**
- * Lexical error occurred.
- */
- static final int LEXICAL_ERROR = 0;
-
- /**
- * An attempt was made to create a second instance of a static token manager.
- */
- static final int STATIC_LEXER_ERROR = 1;
-
- /**
- * Tried to change to an invalid lexical state.
- */
- static final int INVALID_LEXICAL_STATE = 2;
-
- /**
- * Detected (and bailed out of) an infinite loop in the token manager.
- */
- static final int LOOP_DETECTED = 3;
-
- /**
- * Indicates the reason why the exception is thrown. It will have
- * one of the above 4 values.
- */
- int errorCode;
-
- /**
- * Replaces unprintable characters by their escaped (or unicode escaped)
- * equivalents in the given string
- */
- protected static final String addEscapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4, s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
- /**
- * Returns a detailed message for the Error when it is thrown by the
- * token manager to indicate a lexical error.
- * Parameters :
- * EOFSeen : indicates if EOF caused the lexical error
- * curLexState : lexical state in which this error occurred
- * errorLine : line number when the error occurred
- * errorColumn : column number when the error occurred
- * errorAfter : prefix that was seen before this error occurred
- * curchar : the offending character
- * Note: You can customize the lexical error message by modifying this method.
- */
- protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
- return("Lexical error at line " +
- errorLine + ", column " +
- errorColumn + ". Encountered: " +
- (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
- "after : \"" + addEscapes(errorAfter) + "\"");
- }
-
- /**
- * You can also modify the body of this method to customize your error messages.
- * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
- * of end-users concern, so you can return something like :
- *
- * "Internal Error : Please file a bug report .... "
- *
- * from this method for such cases in the release version of your parser.
- */
- public String getMessage() {
- return super.getMessage();
- }
-
- /*
- * Constructors of various flavors follow.
- */
-
- /** No arg constructor. */
- public TokenMgrError() {
- }
-
- /** Constructor with message and reason. */
- public TokenMgrError(String message, int reason) {
- super(message);
- errorCode = reason;
- }
-
- /** Full Constructor. */
- public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
- this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
- }
-}
-/* JavaCC - OriginalChecksum=69448ec97987e87f0f4fc003d5ed03a3 (do not edit this line) */
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONDataException.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.mapper;
-
-/**
- * @author harsha
- */
-public class JSONDataException extends Exception {
-
- private static final long serialVersionUID = 2430707794210680967L;
-
- public JSONDataException() {
- super();
- }
-
- public JSONDataException(String s) {
- super(s);
- }
-
- public JSONDataException(String s, Throwable ex) {
- super(s, ex);
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMapper.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.mapper;
-
-import com.oracle.jmx.remote.rest.json.JSONElement;
-
-/**
- * @author harsha
- */
-public interface JSONMapper {
- public Object toJavaObject(JSONElement jsonValue) throws JSONDataException;
-
- public JSONElement toJsonValue(Object data) throws JSONMappingException;
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingException.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.mapper;
-
-/**
- * @author harsha
- */
-public class JSONMappingException extends Exception {
-
- private static final long serialVersionUID = -3099452281524742227L;
-
- public static final JSONMappingException UNABLE_TO_MAP = new JSONMappingException("Unable to map types");
-
- public JSONMappingException() {
- super();
- }
-
- public JSONMappingException(String s) {
- super(s);
- }
-
- public JSONMappingException(String s, Throwable ex) {
- super(s, ex);
- }
-}
--- a/src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingFactory.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,773 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.jmx.remote.rest.mapper;
-
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.openmbean.*;
-import java.lang.reflect.Array;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-/**
- * @author harsha
- */
-public final class JSONMappingFactory {
-
- public static final JSONMappingFactory INSTANCE;
- private static final Map<Class<?>, JSONMapper> typeMapper;
- private static final Map<String, Class<?>> primitiveMap = new HashMap<>();
-
- static {
- // Make order of Initialization explicit
- typeMapper = new HashMap<>();
-
- primitiveMap.put("boolean", Boolean.TYPE);
- primitiveMap.put("int", Integer.TYPE);
- primitiveMap.put("long", Long.TYPE);
- primitiveMap.put("double", Double.TYPE);
- primitiveMap.put("float", Float.TYPE);
- primitiveMap.put("bool", Boolean.TYPE);
- primitiveMap.put("char", Character.TYPE);
- primitiveMap.put("byte", Byte.TYPE);
- primitiveMap.put("void", Void.TYPE);
- primitiveMap.put("short", Short.TYPE);
-
- INSTANCE = new JSONMappingFactory();
- }
-
- private JSONMappingFactory() {
-
- typeMapper.put(void.class, new VoidMapper());
- typeMapper.put(Void.class, new VoidMapper());
-
- typeMapper.put(boolean.class, new BooleanMapper());
- typeMapper.put(Boolean.class, new BooleanMapper());
-
- typeMapper.put(byte.class, new ByteMapper());
- typeMapper.put(Byte.class, new ByteMapper());
-
- typeMapper.put(short.class, new ShortMapper());
- typeMapper.put(Short.class, new ShortMapper());
-
- typeMapper.put(int.class, new IntegerMapper());
- typeMapper.put(Integer.class, new IntegerMapper());
-
- typeMapper.put(long.class, new LongMapper());
- typeMapper.put(Long.class, new LongMapper());
-
- typeMapper.put(float.class, new FloatMapper());
- typeMapper.put(Float.class, new FloatMapper());
-
- typeMapper.put(double.class, new DoubleMapper());
- typeMapper.put(Double.class, new DoubleMapper());
-
- typeMapper.put(char.class, new CharacterMapper());
- typeMapper.put(Character.class, new CharacterMapper());
-
- typeMapper.put(String.class, new StringMapper());
- typeMapper.put(BigInteger.class, new BigIntegerMapper());
- typeMapper.put(BigDecimal.class, new BigDecimalMapper());
- typeMapper.put(ObjectName.class, new ObjectNameMapper());
- typeMapper.put(Date.class, new DateMapper());
- }
-
- private Class<?> getArrayComponent(Class<?> cls) {
- if (cls == null) {
- return cls;
- }
- Class<?> compType = cls;
- // TODO: Add check for max array dimention of 15
- while (compType.isArray()) {
- compType = compType.getComponentType();
- }
- return compType;
- }
-
- private Object getArrayElement(Object arrayObj) {
- if (arrayObj != null && arrayObj.getClass().isArray()) {
- while (arrayObj.getClass().isArray()) {
- Class<?> componentType = arrayObj.getClass().getComponentType();
- if (Array.getLength(arrayObj) > 0) {
- Object component = null;
- for (int i = 0; i < Array.getLength(arrayObj); i++) {
- component = Array.get(arrayObj, i);
- if (component != null) {
- break;
- }
- }
- if (component == null) {
- return null;
- }
- if (componentType.isPrimitive()) {
- componentType = component.getClass();
- }
- arrayObj = componentType.cast(component);
- } else {
- return null;
- }
- }
- }
- return arrayObj;
- }
-
- // TODO: This should be access controlled. Define new permissions
- public void addMapping(Class<?> cls, JSONMapper mapper) {
- Class<?> input = cls;
- if (cls.isArray()) {
- input = getArrayComponent(cls);
- }
- if (!typeMapper.containsKey(input)) {
- typeMapper.put(input, mapper);
- }
- }
-
- public JSONMapper getTypeMapper(Object object) {
- return getTypeMapper(object, true);
- }
-
- private JSONMapper getTypeMapper(Object object, boolean deepTypeCheck) {
- if (object == null) return null;
- Object obj = object;
- Class<?> cls = object.getClass();
- if (cls.isArray()) {
- Object arrayElement = getArrayElement(obj);
- if (arrayElement instanceof CompositeData) {
- CompositeData cds = (CompositeData) arrayElement;
- return new OpenArrayTypeMapper(cls, cds.getCompositeType());
- } else if (arrayElement instanceof TabularData) {
- TabularData tds = (TabularData) arrayElement;
- return new OpenArrayTypeMapper(cls, tds.getTabularType());
- }
- }
-
- if (object instanceof CompositeData) {
- CompositeData cd = (CompositeData) object;
- return getTypeMapper(cd.getCompositeType());
- } else if (object instanceof TabularData) {
- TabularData cds = (TabularData) object;
- return getTypeMapper(cds.getTabularType());
- } else if (object instanceof Collection<?>) {
- if (deepTypeCheck) {
- Collection<?> c = (Collection<?>) object;
- boolean unknownMapper = c.stream().anyMatch(k -> (k != null) && (getTypeMapper(k) == null));
- if (unknownMapper)
- return null;
- }
- return new CollectionMapper();
- } else if (object instanceof Map<?, ?>) {
- if (deepTypeCheck) {
- Map<?, ?> map = (Map<?, ?>) object;
- boolean unknownMapper = map.keySet().stream().
- anyMatch(k -> ((k != null) && (getTypeMapper(k) == null)
- || (map.get(k) != null && getTypeMapper(map.get(k)) == null)));
- if (unknownMapper)
- return null;
- }
- return new MapMapper();
- } else {
- return getTypeMapper(cls);
- }
- }
-
- public JSONMapper getTypeMapper(Class<?> type) {
- if (type == null) return null;
- if (type.isArray()) {
- Class<?> compType = getArrayComponent(type);
- if (typeMapper.get(compType) != null) {
- return new GenericArrayMapper(type);
- } else {
- return null;
- }
- }
- return typeMapper.get(type);
- }
-
- public JSONMapper getTypeMapper(OpenType<?> type) {
- if (type instanceof CompositeType) {
- return new OpenCompositeTypeMapper((CompositeType) type);
- } else if (type instanceof SimpleType) {
- try {
- return getTypeMapper(Class.forName(((SimpleType) type).getClassName()));
- } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
- throw new RuntimeException(ex);
- }
- } else if (type instanceof ArrayType) {
- try {
- ArrayType<?> at = (ArrayType) type;
- Class<?> arrayClass = Class.forName(type.getClassName());
- return new OpenArrayTypeMapper(arrayClass, at.getElementOpenType());
- } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
- throw new RuntimeException(ex);
- }
- } else if (type instanceof TabularType) {
- return new OpenTabularTypeMapper((TabularType) type);
- }
- return null; //keep compiler happy
- }
-
- public boolean isTypeMapped(String type) throws ClassNotFoundException {
- if (primitiveMap.get(type) != null) {
- return true;
- }
- Class<?> inputCls = Class.forName(type);
- inputCls = getArrayComponent(inputCls);
- if (inputCls.equals(CompositeData.class) || inputCls.equals(TabularData.class)
- || inputCls.equals(CompositeDataSupport.class) || inputCls.equals(TabularDataSupport.class)) {
- return true;
- }
- return JSONMappingFactory.INSTANCE.getTypeMapper(inputCls) != null;
- }
-
- private static class OpenArrayTypeMapper extends GenericArrayMapper {
-
- OpenArrayTypeMapper(Class<?> type, OpenType<?> elementOpenType) {
- super(type);
- mapper = JSONMappingFactory.INSTANCE.getTypeMapper(elementOpenType);
- }
- }
-
- // This mapper array type for any java class
- private static class GenericArrayMapper implements JSONMapper {
-
- private final Class<?> type;
- protected JSONMapper mapper;
-
- GenericArrayMapper(Class<?> type) {
- this.type = type;
- mapper = JSONMappingFactory.INSTANCE.getTypeMapper(JSONMappingFactory.INSTANCE.getArrayComponent(type));
- }
-
- private Object handleArrayType(Class<?> classType, JSONElement jsonValue) throws JSONDataException {
- if (!(jsonValue instanceof JSONArray)) {
- throw new JSONDataException("Invald JSON data format");
- }
- JSONArray jarr = (JSONArray) jsonValue;
- Class<?> compType = classType.getComponentType();
- Object resultArray = Array.newInstance(compType, jarr.size());
-
- for (int i = 0; i < jarr.size(); i++) {
- if (compType != null && compType.isArray()) {
- Array.set(resultArray, i, handleArrayType(compType, jarr.get(i)));
- } else {
- Array.set(resultArray, i, mapper.toJavaObject(jarr.get(i)));
- }
- }
- return resultArray;
- }
-
- @Override
- public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
- return handleArrayType(type, jsonValue);
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- if (data == null) {
- return null;
- }
- if (!data.getClass().equals(type)) {
- throw new JSONMappingException("Illegal type : " + data.getClass());
- }
- return getJasonValue(data);
- }
-
- private JSONElement getJasonValue(Object data) throws JSONMappingException {
- if (data == null) {
- return null;
- }
- if (!data.getClass().isArray()) {
- return mapper.toJsonValue(data);
- } else {
- JSONArray jArray = new JSONArray();
- for (int i = 0; i < Array.getLength(data); i++) {
- jArray.add(getJasonValue(Array.get(data, i)));
- }
- return jArray;
- }
- }
- }
-
- /*
- Mapper for compositeType. CompositeData cannot be mapped without it's associated
- OpenType
- */
- private static class OpenCompositeTypeMapper implements JSONMapper {
-
- private final CompositeType type;
-
- OpenCompositeTypeMapper(CompositeType type) {
- this.type = type;
- }
-
- @Override
- public CompositeDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (!(jsonValue instanceof JSONObject)) {
- throw new JSONDataException("JSON String not an object");
- }
-
- JSONObject jObject = (JSONObject) jsonValue;
- Map<String, Object> compositeDataMap = new HashMap<>();
- for (String itemName : type.keySet()) {
- OpenType<?> oType = type.getType(itemName);
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
- compositeDataMap.put(itemName, typeMapper.toJavaObject(jObject.get(itemName)));
- }
- try {
- return new CompositeDataSupport(type, compositeDataMap);
- } catch (OpenDataException ex) {
- throw new JSONDataException("Could not create CompositeData", ex);
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object d) throws JSONMappingException {
- CompositeData data = (CompositeData) d;
- if (data == null) {
- return null;
- }
- JSONObject jObject = new JSONObject();
- for (String itemName : type.keySet()) {
- OpenType<?> oType = type.getType(itemName);
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
- if (typeMapper != null) {
- jObject.put(itemName, typeMapper.toJsonValue(data.get(itemName)));
- } else {
- System.out.println("Unable to find mapper for : " + oType);
- }
- }
- return jObject;
- }
- }
-
- private static class OpenTabularTypeMapper implements JSONMapper {
-
- private final TabularType type;
-
- public OpenTabularTypeMapper(TabularType type) {
- this.type = type;
- }
-
- /*
- Tabular data in JSON can follow below schema
- {
- "keys" : [<list of elements>],
- "rows": [{ <CompositeData> }]
- }
- */
- @Override
- public TabularDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- if (data == null) {
- return null;
- }
- TabularDataSupport tds = (TabularDataSupport) data;
- JSONArray jsonArray = new JSONArray();
- for (Map.Entry<Object, Object> a : tds.entrySet()) {
- CompositeData cds = (CompositeData) a.getValue();
- JSONMapper cdsMapper = JSONMappingFactory.INSTANCE.getTypeMapper(cds);
- if (cdsMapper != null) {
- jsonArray.add(cdsMapper.toJsonValue(cds));
- }
- }
- return jsonArray;
- }
- }
-
- private static class VoidMapper implements JSONMapper {
- @Override
- public Void toJavaObject(JSONElement jsonValue) throws JSONDataException {
- return null;
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return null;
- }
- }
-
- private static class BooleanMapper implements JSONMapper {
-
- @Override
- public Boolean toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Boolean) {
- return (Boolean) ((JSONPrimitive) jsonValue).getValue();
- } else {
- throw new JSONDataException("Invalid type convertion - cannot convert "
- + ((JSONPrimitive) jsonValue).getValue()
- + "(" + ((JSONPrimitive) jsonValue).getValue().getClass() + ")" + " to boolean");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Boolean) data);
- }
- }
-
- private static class ByteMapper implements JSONMapper {
-
- @Override
- public Byte toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return ((Long) ((JSONPrimitive) jsonValue).getValue()).byteValue();
- } else {
- throw new JSONDataException("Invalid type convertion - cannot convert "
- + (((JSONPrimitive) jsonValue).getValue().getClass()) + " to byte");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Byte) data);
- }
- }
-
- private static class ShortMapper implements JSONMapper {
-
- @Override
- public Short toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return ((Long) ((JSONPrimitive) jsonValue).getValue()).shortValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Short) data);
- }
- }
-
- private static class IntegerMapper implements JSONMapper {
-
- @Override
- public Integer toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return ((Long) ((JSONPrimitive) jsonValue).getValue()).intValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Integer) data);
- }
- }
-
- private static class LongMapper implements JSONMapper {
-
- @Override
- public Long toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return (Long) ((JSONPrimitive) jsonValue).getValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Long) data);
- }
- }
-
- private static class FloatMapper implements JSONMapper {
-
- @Override
- public Float toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
- return ((Double) ((JSONPrimitive) jsonValue).getValue()).floatValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Float) data);
- }
- }
-
- private static class DoubleMapper implements JSONMapper {
-
- @Override
- public Double toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return (Double) ((JSONPrimitive) jsonValue).getValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Double) data);
- }
- }
-
- private static class CharacterMapper implements JSONMapper {
-
- @Override
- public Character toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
- String data = ((String) ((JSONPrimitive) jsonValue).getValue());
- if (data.length() < 1) {
- throw new JSONDataException("Invalid char");
- }
- return data.charAt(0);
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((Character) data);
- }
- }
-
- private static class StringMapper implements JSONMapper {
-
- @Override
- public String toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
- return (String) ((JSONPrimitive) jsonValue).getValue();
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive((String) data);
- }
- }
-
- private static class BigDecimalMapper implements JSONMapper {
-
- @Override
- public BigDecimal toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
- return BigDecimal.valueOf((Double) ((JSONPrimitive) jsonValue).getValue());
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive(((BigDecimal) data).doubleValue());
- }
- }
-
- private static class BigIntegerMapper implements JSONMapper {
-
- @Override
- public BigInteger toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
- return BigInteger.valueOf((Long) ((JSONPrimitive) jsonValue).getValue());
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive(((BigInteger) data).longValue());
- }
- }
-
- private static class ObjectNameMapper implements JSONMapper {
-
- @Override
- public ObjectName toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
- try {
- return new ObjectName((String) ((JSONPrimitive) jsonValue).getValue());
- } catch (MalformedObjectNameException ex) {
- throw new JSONDataException("Invalid Objectname");
- }
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive(data.toString());
- }
- }
-
- private static class DateMapper implements JSONMapper {
-
- private final DateFormat df = new SimpleDateFormat("YYYY-MM-DD");
-
- @Override
- public Date toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
- String data = ((String) ((JSONPrimitive) jsonValue).getValue());
- try {
- return df.parse(data);
- } catch (ParseException ex) {
- throw new JSONDataException("Invalid Data " + data);
- }
- } else {
- throw new JSONDataException("Invalid JSON");
- }
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- return new JSONPrimitive(df.format((Date) data));
- }
- }
-
- private static final class MapMapper implements JSONMapper {
-
- @Override
- public Map<String, Object> toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONObject) {
- JSONObject obj = (JSONObject) jsonValue;
- Map<String, Object> result = new HashMap<>(obj.size());
- for (String k : result.keySet()) {
- JSONElement elem = obj.get(k);
- if (elem instanceof JSONPrimitive) {
- result.put(k, ((JSONPrimitive) elem).getValue());
- } else {
- JSONMapper mapper;
- if (elem instanceof JSONObject) {
- mapper = new MapMapper();
- result.put(k, mapper.toJavaObject(elem));
- } else if (elem instanceof JSONArray) {
- mapper = new CollectionMapper();
- result.put(k, mapper.toJavaObject(elem));
- } else {
- throw new JSONDataException("Unable to map : " + elem.getClass());
- }
- }
- }
- return result;
- }
- throw new JSONDataException("Inalid input");
- }
-
- @Override
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- if (data instanceof Map) {
- JSONObject jobj = new JSONObject();
- Map<?, ?> input = (Map<?, ?>) data;
- for (Object k : input.keySet()) {
- String key = k.toString();
- final Object value = input.get(k);
- if (value == null) {
- jobj.put(key, (JSONElement) null);
- } else {
- JSONMapper mapper = JSONMappingFactory.INSTANCE
- .getTypeMapper(value,false); // Disable repeated type checking
- if (mapper == null) {
- throw new JSONMappingException("Unable to map : " + value);
- }
- jobj.put(key, mapper.toJsonValue(value));
- }
- }
- return jobj;
- } else {
- throw new JSONMappingException("Invalid Input");
- }
- }
- }
-
- private static final class CollectionMapper implements JSONMapper {
-
- public CollectionMapper() {
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
- if (jsonValue instanceof JSONArray) {
- JSONArray jarr = (JSONArray) jsonValue;
- List<Object> result = new ArrayList<>(jarr.size());
- for (JSONElement elem : jarr) {
- if (elem instanceof JSONPrimitive) {
- result.add(((JSONPrimitive) elem).getValue());
- } else {
- JSONMapper mapper;
- if (elem instanceof JSONObject) {
- mapper = new MapMapper();
- result.add(mapper.toJavaObject(elem));
- } else if (elem instanceof JSONArray) {
- mapper = new CollectionMapper();
- result.add(mapper.toJavaObject(elem));
- } else {
- throw new JSONDataException("Unable to map : " + elem.getClass());
- }
- }
- }
- return result;
- }
- throw new JSONDataException("Inalid input");
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public JSONElement toJsonValue(Object data) throws JSONMappingException {
- if (data instanceof Collection) {
- JSONArray jarr = new JSONArray();
- Collection<?> c = (Collection<?>) data;
- Iterator<?> itr = c.iterator();
- while (itr.hasNext()) {
- Object next = itr.next();
- JSONMapper typeMapper = JSONMappingFactory.INSTANCE.
- getTypeMapper(next,false); // Disable repeated type checking for collection
- if (typeMapper == null) {
- throw JSONMappingException.UNABLE_TO_MAP;
- }
- jarr.add(typeMapper.toJsonValue(next));
- }
- return jarr;
- } else {
- throw new JSONMappingException("Invalid Input");
- }
- }
- }
-}
--- a/src/java.management.rest/share/classes/javax/management/remote/rest/JmxRestAdapter.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-package javax.management.remote.rest;
-
-import javax.management.MBeanServer;
-
-public interface JmxRestAdapter {
-
- public void start();
-
- public void stop();
-
- public String getUrl();
-
- public MBeanServer getMBeanServer();
-}
\ No newline at end of file
--- a/src/java.management.rest/share/classes/javax/management/remote/rest/PlatformRestAdapter.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rest;
-
-import com.oracle.jmx.remote.rest.http.MBeanServerCollectionResource;
-import com.oracle.jmx.remote.rest.http.MBeanServerResource;
-import com.sun.net.httpserver.HttpServer;
-import com.sun.net.httpserver.HttpsConfigurator;
-import com.sun.net.httpserver.HttpsServer;
-
-import javax.management.*;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.security.KeyStore;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * This is the root class that initializes the HTTPServer and
- * REST adapter for platform mBeanServer.
- *
- * @since 11
- */
-public class PlatformRestAdapter implements MBeanServerFactoryListener {
-
- /*
- * Initializes HTTPServer with settings from config file
- * acts as container for platform rest adapter
- */
- private static HttpServer httpServer = null;
-
- // Save configuration to be used for other MBeanServers
- private static Map<String, Object> env;
- private static List<MBeanServerResource> restAdapters = new CopyOnWriteArrayList<>();
- private static final int maxThreadCount = 5;
-
- private PlatformRestAdapter() {
- }
-
- private static class HttpThreadFactory implements ThreadFactory {
- private final ThreadGroup group;
- private final AtomicInteger threadNumber = new AtomicInteger(1);
- private final String namePrefix = "http-thread-";
-
- HttpThreadFactory() {
- SecurityManager s = System.getSecurityManager();
- group = (s != null) ? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
- }
-
- public Thread newThread(Runnable r) {
- Thread t = new Thread(group, r,
- namePrefix + threadNumber.getAndIncrement(),
- 0);
- if (t.isDaemon())
- t.setDaemon(false);
- if (t.getPriority() != Thread.NORM_PRIORITY)
- t.setPriority(Thread.NORM_PRIORITY);
- return t;
- }
- }
-
- /**
- * Starts the HTTP server with confiuration specified in properties.
- * The configuration properties are Interface name/IP, port and SSL configuration
- * By default the server binds to address '0.0.0.0' and port '0'. SSL is off by default. [TODO]The
- * keyStore will be created one if not configured and the private key and a public certificate will
- * be generated[/TODO].
- * Below properties are used to configure the HTTP server.
- * com.sun.management.jmxremote.rest.port
- * com.sun.management.jmxremote.rest.host
- * com.sun.management.jmxremote.ssl
- * com.sun.management.jmxremote.ssl.config.file
- * javax.net.ssl.keyStore
- * javax.net.ssl.trustStore
- * javax.net.ssl.keyStorePassword
- * javax.net.ssl.trustStorePassword
- *
- * @param properties Config properties for the HTTP server.
- * If null or if any properties are not specified, default values will be assumed.
- * @throws IOException If the server could not be created
- */
- public static synchronized void init(Properties properties) throws IOException {
- if (httpServer == null) {
- if (properties == null || properties.isEmpty()) {
- properties = new Properties();
- properties.setProperty("com.sun.management.jmxremote.ssl", "false");
- properties.setProperty("com.sun.management.jmxremote.authenticate", "false");
- properties.setProperty("com.sun.management.jmxremote.rest.port", "0");
- }
- final int port;
- try {
- port = Integer.parseInt(properties.getProperty(PropertyNames.PORT, DefaultValues.PORT));
- } catch (NumberFormatException x) {
- throw new IllegalArgumentException("Invalid string for port");
- }
- if (port < 0) {
- throw new IllegalArgumentException("Invalid string for port");
- }
-
- String host = properties.getProperty(PropertyNames.HOST, DefaultValues.HOST);
-
- boolean useSSL = Boolean.parseBoolean(properties.getProperty(
- PropertyNames.USE_SSL, DefaultValues.USE_SSL));
- if (useSSL) {
- final String sslConfigFileName
- = properties.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);
- SSLContext ctx = getSSlContext(sslConfigFileName);
- if (ctx != null) {
- HttpsServer server = HttpsServer.create(new InetSocketAddress(host, port), 0);
- server.setHttpsConfigurator(new HttpsConfigurator(ctx));
- httpServer = server;
- } else {
- httpServer = HttpServer.create(new InetSocketAddress(host, port), 0);
- }
- } else {
- httpServer = HttpServer.create(new InetSocketAddress(host, port), 0);
- }
-
- new MBeanServerCollectionResource(restAdapters, httpServer);
- httpServer.setExecutor(Executors.newFixedThreadPool(maxThreadCount, new HttpThreadFactory()));
- httpServer.start();
- startDefaultRestAdapter(properties);
- }
- }
-
- private static void startDefaultRestAdapter(Properties properties) {
- env = new HashMap<>();
- // Do we use authentication?
- final String useAuthenticationStr
- = properties.getProperty(PropertyNames.USE_AUTHENTICATION,
- DefaultValues.USE_AUTHENTICATION);
- final boolean useAuthentication
- = Boolean.valueOf(useAuthenticationStr);
-
- String loginConfigName;
- String passwordFileName;
-
- if (useAuthentication) {
- env.put("jmx.remote.x.authentication", Boolean.TRUE);
- // Get non-default login configuration
- loginConfigName
- = properties.getProperty(PropertyNames.LOGIN_CONFIG_NAME);
- env.put("jmx.remote.x.login.config", loginConfigName);
-
- if (loginConfigName == null) {
- // Get password file
- passwordFileName
- = properties.getProperty(PropertyNames.PASSWORD_FILE_NAME);
- env.put("jmx.remote.x.password.file", passwordFileName);
- }
- }
- MBeanServerResource adapter = new MBeanServerResource(httpServer, ManagementFactory.getPlatformMBeanServer(), "platform", env);
- adapter.start();
- restAdapters.add(adapter);
- }
-
- /**
- * Wraps the mbeanServer in a REST adapter. The mBeanServer will be accessible over REST APIs
- * at supplied context. env parameter configures authentication parameters for the MBeanServer.
- *
- * @param mbeanServer The MBeanServer to be wrapped in REST adapter
- * @param context The context in HTTP server under which this MBeanServer will be available over REST
- * If it is null or empty, a context will be generated
- * @param env configures authemtication parameters for accessing the MBeanServer over this adapter
- * If null, configuration from default rest adapter will be used.
- * Below is the list of properties.
- * <p>
- * jmx.remote.x.authentication : enable/disable user authentication
- * jmx.remote.authenticator : Instance of a JMXAuthenticator
- * jmx.remote.x.login.config : JAAS login conguration
- * jmx.remote.x.password.file : file name for default JAAS login configuration
- * @return an Instance of REST adapter that allows to start/stop the adapter
- */
- public static synchronized JmxRestAdapter newRestAdapter(MBeanServer mbeanServer, String context, Map<String, ?> env) {
- if (httpServer == null) {
- throw new IllegalStateException("Platform Adapter not initialized");
- }
-
- MBeanServerResource server = restAdapters.stream()
- .filter(s -> areMBeanServersEqual(s.getMBeanServer(), mbeanServer))
- .findFirst()
- .get();
- if (server == null) {
- MBeanServerResource adapter = new MBeanServerResource(httpServer, mbeanServer, context, env);
- adapter.start();
- restAdapters.add(adapter);
- return adapter;
- } else {
- throw new IllegalArgumentException("MBeanServer already registered at " + server.getUrl());
- }
- }
-
- private static boolean areMBeanServersEqual(MBeanServer server1, MBeanServer server2) {
- MBeanServerDelegateMBean bean1 = JMX.newMBeanProxy(server1, MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
- MBeanServerDelegateMBean bean2 = JMX.newMBeanProxy(server2, MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
- return bean1.getMBeanServerId().equalsIgnoreCase(bean2.getMBeanServerId());
- }
-
- public synchronized static void stop() {
- restAdapters.forEach(r -> r.stop());
- restAdapters.clear();
- if (httpServer != null) {
- ExecutorService executor = (ExecutorService) httpServer.getExecutor();
- executor.shutdownNow();
- try {
- executor.awaitTermination(30, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- }
- httpServer.stop(0);
- httpServer = null;
- }
- }
-
- /*
- This auto addition of MBeanServer to rest adapter must be controlled by a system property
- com.sun.management.jmxremote.mbeanserver.autoadd=true/false
- This allows application MBeans to be be availble over REST without any changes to application code.
- */
- @Override
- public void onMBeanServerCreated(MBeanServer mBeanServer) {
- try {
- newRestAdapter(mBeanServer, "", env);
- } catch (IllegalArgumentException | IllegalStateException e) {
- }
- }
-
- @Override
- public void onMBeanServerRemoved(MBeanServer mBeanServer) {
-
- }
-
- public static synchronized String getDomain() {
- if (httpServer == null) {
- throw new IllegalStateException("Platform rest adapter not initialized");
- }
- try {
- if (httpServer instanceof HttpsServer) {
- return "https://" + InetAddress.getLocalHost().getCanonicalHostName() + ":" + httpServer.getAddress().getPort();
- }
- return "http://" + InetAddress.getLocalHost().getCanonicalHostName() + ":" + httpServer.getAddress().getPort();
- } catch (UnknownHostException ex) {
- return "http://localhost" + ":" + httpServer.getAddress().getPort();
- }
- }
-
- public static synchronized String getBaseURL() {
- return getDomain() + "/jmx/servers";
- }
-
- private static SSLContext getSSlContext(String sslConfigFileName) {
- final String keyStore, keyStorePassword, trustStore, trustStorePassword;
-
- try {
- if (sslConfigFileName == null || sslConfigFileName.isEmpty()) {
- keyStore = System.getProperty(PropertyNames.SSL_KEYSTORE_FILE);
- keyStorePassword = System.getProperty(PropertyNames.SSL_KEYSTORE_PASSWORD);
- trustStore = System.getProperty(PropertyNames.SSL_TRUSTSTORE_FILE);
- trustStorePassword = System.getProperty(PropertyNames.SSL_TRUSTSTORE_PASSWORD);
- } else {
- Properties p = new Properties();
- BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
- p.load(bin);
- keyStore = p.getProperty(PropertyNames.SSL_KEYSTORE_FILE);
- keyStorePassword = p.getProperty(PropertyNames.SSL_KEYSTORE_PASSWORD);
- trustStore = p.getProperty(PropertyNames.SSL_TRUSTSTORE_FILE);
- trustStorePassword = p.getProperty(PropertyNames.SSL_TRUSTSTORE_PASSWORD);
- }
-
- char[] keyStorePasswd = null;
- if (keyStorePassword.length() != 0) {
- keyStorePasswd = keyStorePassword.toCharArray();
- }
-
- char[] trustStorePasswd = null;
- if (trustStorePassword.length() != 0) {
- trustStorePasswd = trustStorePassword.toCharArray();
- }
-
- KeyStore ks = null;
- if (keyStore != null) {
- ks = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream ksfis = new FileInputStream(keyStore);
- ks.load(ksfis, keyStorePasswd);
-
- }
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(
- KeyManagerFactory.getDefaultAlgorithm());
- kmf.init(ks, keyStorePasswd);
-
- KeyStore ts = null;
- if (trustStore != null) {
- ts = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream tsfis = new FileInputStream(trustStore);
- ts.load(tsfis, trustStorePasswd);
- }
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(ts);
-
- SSLContext ctx = SSLContext.getInstance("SSL");
- ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
- return ctx;
- } catch (Exception ex) {
- }
- return null;
- }
-
- /**
- * Default values for JMX configuration properties.
- */
- static interface DefaultValues {
-
- public static final String PORT = "0";
- public static final String HOST = "0.0.0.0";
- public static final String USE_SSL = "false";
- public static final String USE_AUTHENTICATION = "false";
- public static final String PASSWORD_FILE_NAME = "jmxremote.password";
- }
-
- /**
- * Names of JMX configuration properties.
- */
- public static interface PropertyNames {
-
- public static final String PORT
- = "com.sun.management.jmxremote.rest.port";
- public static final String HOST
- = "com.sun.management.jmxremote.host";
- public static final String USE_SSL
- = "com.sun.management.jmxremote.ssl";
- public static final String SSL_CONFIG_FILE_NAME
- = "com.sun.management.jmxremote.ssl.config.file";
- public static final String SSL_KEYSTORE_FILE
- = "javax.net.ssl.keyStore";
- public static final String SSL_TRUSTSTORE_FILE
- = "javax.net.ssl.trustStore";
- public static final String SSL_KEYSTORE_PASSWORD
- = "javax.net.ssl.keyStorePassword";
- public static final String SSL_TRUSTSTORE_PASSWORD
- = "javax.net.ssl.trustStorePassword";
- public static final String USE_AUTHENTICATION
- = "com.sun.management.jmxremote.authenticate";
- public static final String PASSWORD_FILE_NAME
- = "com.sun.management.jmxremote.password.file";
- public static final String LOGIN_CONFIG_NAME
- = "com.sun.management.jmxremote.login.config";
- }
-}
--- a/src/java.management.rest/share/classes/module-info.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-module java.management.rest {
-
- requires transitive java.management;
- requires jdk.httpserver;
-
- exports javax.management.remote.rest;
-}
--- a/src/java.management/share/classes/javax/management/MBeanServerFactory.java Fri Jan 05 13:42:53 2018 +0530
+++ b/src/java.management/share/classes/javax/management/MBeanServerFactory.java Fri Jan 19 13:46:27 2018 +0530
@@ -335,7 +335,6 @@
"MBeanServerBuilder.newMBeanServer() returned null";
throw new JMRuntimeException(msg);
}
- notifyListenersCreated(mbeanServer);
return mbeanServer;
}
}
@@ -429,7 +428,6 @@
"MBeanServer was not in list!");
throw new IllegalArgumentException("MBeanServer was not in list!");
}
- notifyListenersRemoved(mbs);
}
private static final ArrayList<MBeanServer> mBeanServerList =
@@ -540,31 +538,4 @@
checkMBeanServerBuilder();
return builder;
}
-
- private static final List<MBeanServerFactoryListener> listeners = new LinkedList<>();
-
- /**
- * Add listener
- * @param listener the listener object
- */
- public static void addListener(MBeanServerFactoryListener listener) {
- if(!listeners.contains(listener))
- listeners.add(listener);
- }
-
- /**
- * remove listener
- * @param listener the listener object
- */
- public static void removeListener(MBeanServerFactoryListener listener) {
- listeners.remove(listener);
- }
-
- private static void notifyListenersCreated(MBeanServer server) {
- listeners.forEach(l -> l.onMBeanServerCreated(server));
- }
-
- private static void notifyListenersRemoved(MBeanServer server) {
- listeners.forEach(l -> l.onMBeanServerRemoved(server));
- }
}
--- a/src/java.management/share/classes/javax/management/MBeanServerFactoryListener.java Fri Jan 05 13:42:53 2018 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-package javax.management;
-
-/**
- * Listener interface to get notified when MBeanServer
- * is created/released
- */
-public interface MBeanServerFactoryListener {
- /**
- * When MbeanServer is added
- * @param mBeanServer the mBeanServer
- */
- public void onMBeanServerCreated(MBeanServer mBeanServer);
-
- /**
- * When MBeanServer is released
- * @param mBeanServer the mBeanServer
- */
- public void onMBeanServerRemoved(MBeanServer mBeanServer);
-}
--- a/src/java.management/share/classes/module-info.java Fri Jan 05 13:42:53 2018 +0530
+++ b/src/java.management/share/classes/module-info.java Fri Jan 19 13:46:27 2018 +0530
@@ -52,7 +52,7 @@
jdk.management.agent;
exports com.sun.jmx.remote.security to
java.management.rmi,
- java.management.rest,
+ jdk.management.rest,
jdk.management.agent;
exports com.sun.jmx.remote.util to
java.management.rmi;
--- a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java Fri Jan 05 13:42:53 2018 +0530
+++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java Fri Jan 19 13:46:27 2018 +0530
@@ -32,7 +32,6 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rest.PlatformRestAdapter;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
@@ -246,6 +245,7 @@
"com.sun.management.jmxremote.localConnectorAddress";
private static final String SNMP_AGENT_NAME =
"SnmpAgent";
+ private static final String REST_ADAPTER_NAME = "RestAdapter";
private static final String JDP_DEFAULT_ADDRESS = "224.0.23.178";
private static final int JDP_DEFAULT_PORT = 7095;
@@ -547,13 +547,23 @@
}
private static void loadRestAdapter(Properties props) {
- try {
- if (props.get(REST_PORT) != null) {
- PlatformRestAdapter.init(props);
- System.out.println("Rest Base URL : " + PlatformRestAdapter.getBaseURL());
- }
- } catch (Throwable ex) {
- ex.printStackTrace();
+ /*
+ * Load the rest adapter service
+ */
+ AgentProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<AgentProvider>) () -> {
+ for (AgentProvider aProvider : ServiceLoader.loadInstalled(AgentProvider.class)) {
+ if (aProvider.getName().equals(REST_ADAPTER_NAME))
+ return aProvider;
+ }
+ return null;
+ }, null
+ );
+
+ if (provider != null) {
+ provider.startAgent(props);
+ } else { // Rest adapter doesn't exist - initialization fails
+ throw new UnsupportedOperationException("Unsupported management property: " + REST_PORT);
}
}
--- a/src/jdk.management.agent/share/classes/module-info.java Fri Jan 05 13:42:53 2018 +0530
+++ b/src/jdk.management.agent/share/classes/module-info.java Fri Jan 19 13:46:27 2018 +0530
@@ -37,9 +37,9 @@
module jdk.management.agent {
requires java.management;
requires java.management.rmi;
- requires java.management.rest;
exports jdk.internal.agent to jdk.jconsole;
+ exports jdk.internal.agent.spi to jdk.management.rest;
uses jdk.internal.agent.spi.AgentProvider;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/JmxRestAdapter.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,14 @@
+package jdk.internal.management.remote.rest;
+
+import javax.management.MBeanServer;
+
+public interface JmxRestAdapter {
+
+ public void start();
+
+ public void stop();
+
+ public String getUrl();
+
+ public MBeanServer getMBeanServer();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/PlatformRestAdapter.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest;
+
+import jdk.internal.management.remote.rest.http.MBeanServerCollectionResource;
+import jdk.internal.management.remote.rest.http.MBeanServerResource;
+import com.sun.net.httpserver.HttpServer;
+import com.sun.net.httpserver.HttpsConfigurator;
+import com.sun.net.httpserver.HttpsServer;
+
+import javax.management.*;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This is the root class that initializes the HTTPServer and
+ * REST adapter for platform mBeanServer.
+ *
+ * @since 11
+ */
+public final class PlatformRestAdapter {
+
+ /*
+ * Initializes HTTPServer with settings from config file
+ * acts as container for platform rest adapter
+ */
+ private static HttpServer httpServer = null;
+
+ // Save configuration to be used for other MBeanServers
+ private static Map<String, Object> env;
+ private static List<MBeanServerResource> restAdapters = new CopyOnWriteArrayList<>();
+ private static final int maxThreadCount = 5;
+
+ private PlatformRestAdapter() {
+ }
+
+ private static class HttpThreadFactory implements ThreadFactory {
+ private final ThreadGroup group;
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+ private final String namePrefix = "http-thread-";
+
+ HttpThreadFactory() {
+ SecurityManager s = System.getSecurityManager();
+ group = (s != null) ? s.getThreadGroup() :
+ Thread.currentThread().getThreadGroup();
+ }
+
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(group, r,
+ namePrefix + threadNumber.getAndIncrement(),
+ 0);
+ if (t.isDaemon())
+ t.setDaemon(false);
+ if (t.getPriority() != Thread.NORM_PRIORITY)
+ t.setPriority(Thread.NORM_PRIORITY);
+ return t;
+ }
+ }
+
+ /**
+ * Starts the HTTP server with the input configuration properties
+ * The configuration properties are Interface name/IP, port and SSL configuration
+ * By default the server binds to address '0.0.0.0' and port '0'. SSL is off by default. [TODO]The
+ * keyStore will be created one if not configured and the private key and a public certificate will
+ * be generated[/TODO].
+ * Below properties are used to configure the HTTP server.
+ * com.sun.management.jmxremote.rest.port
+ * com.sun.management.jmxremote.rest.host
+ * com.sun.management.jmxremote.ssl
+ * com.sun.management.jmxremote.ssl.config.file
+ * javax.net.ssl.keyStore
+ * javax.net.ssl.trustStore
+ * javax.net.ssl.keyStorePassword
+ * javax.net.ssl.trustStorePassword
+ *
+ * @param properties Config properties for the HTTP server.
+ * If null or if any of the properties is not specified, default values will be assumed.
+ * @throws IOException If the server could not be created
+ */
+ public static synchronized void init(Properties properties) throws IOException {
+ if (httpServer == null) {
+ if (properties == null || properties.isEmpty()) {
+ properties = new Properties();
+ properties.setProperty("com.sun.management.jmxremote.ssl", "false");
+ properties.setProperty("com.sun.management.jmxremote.authenticate", "false");
+ properties.setProperty("com.sun.management.jmxremote.rest.port", "0");
+ }
+ final int port;
+ try {
+ port = Integer.parseInt(properties.getProperty(PropertyNames.PORT, DefaultValues.PORT));
+ } catch (NumberFormatException x) {
+ throw new IllegalArgumentException("Invalid string for port");
+ }
+ if (port < 0) {
+ throw new IllegalArgumentException("Invalid string for port");
+ }
+
+ String host = properties.getProperty(PropertyNames.HOST, DefaultValues.HOST);
+
+ boolean useSSL = Boolean.parseBoolean(properties.getProperty(
+ PropertyNames.USE_SSL, DefaultValues.USE_SSL));
+ if (useSSL) {
+ final String sslConfigFileName
+ = properties.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);
+ SSLContext ctx = getSSlContext(sslConfigFileName);
+ if (ctx != null) {
+ HttpsServer server = HttpsServer.create(new InetSocketAddress(host, port), 0);
+ server.setHttpsConfigurator(new HttpsConfigurator(ctx));
+ httpServer = server;
+ } else {
+ httpServer = HttpServer.create(new InetSocketAddress(host, port), 0);
+ }
+ } else {
+ httpServer = HttpServer.create(new InetSocketAddress(host, port), 0);
+ }
+
+ new MBeanServerCollectionResource(restAdapters, httpServer);
+ httpServer.setExecutor(Executors.newFixedThreadPool(maxThreadCount, new HttpThreadFactory()));
+ httpServer.start();
+ startDefaultRestAdapter(properties);
+ }
+ }
+
+ public static boolean isStarted() {
+ return httpServer!=null;
+ }
+
+ private static void startDefaultRestAdapter(Properties properties) {
+ env = new HashMap<>();
+ // Do we use authentication?
+ final String useAuthenticationStr
+ = properties.getProperty(PropertyNames.USE_AUTHENTICATION,
+ DefaultValues.USE_AUTHENTICATION);
+ final boolean useAuthentication
+ = Boolean.valueOf(useAuthenticationStr);
+
+ String loginConfigName;
+ String passwordFileName;
+
+ if (useAuthentication) {
+ env.put("jmx.remote.x.authentication", Boolean.TRUE);
+ // Get non-default login configuration
+ loginConfigName
+ = properties.getProperty(PropertyNames.LOGIN_CONFIG_NAME);
+ env.put("jmx.remote.x.login.config", loginConfigName);
+
+ if (loginConfigName == null) {
+ // Get password file
+ passwordFileName
+ = properties.getProperty(PropertyNames.PASSWORD_FILE_NAME);
+ env.put("jmx.remote.x.password.file", passwordFileName);
+ }
+ }
+ MBeanServerResource adapter = new MBeanServerResource(httpServer, ManagementFactory.getPlatformMBeanServer(), "platform", env);
+ adapter.start();
+ restAdapters.add(adapter);
+ }
+
+ /**
+ * Wraps the mbeanServer in a REST adapter. The mBeanServer will be accessible over REST APIs
+ * at supplied context. env parameter configures authentication parameters for the MBeanServer.
+ *
+ * @param mbeanServer The MBeanServer to be wrapped in REST adapter
+ * @param context The context in HTTP server under which this MBeanServer will be available over REST
+ * If it is null or empty, a context will be generated
+ * @param env configures authemtication parameters for accessing the MBeanServer over this adapter
+ * If null, configuration from default rest adapter will be used.
+ * Below is the list of properties.
+ * <p>
+ * jmx.remote.x.authentication : enable/disable user authentication
+ * jmx.remote.authenticator : Instance of a JMXAuthenticator
+ * jmx.remote.x.login.config : JAAS login conguration
+ * jmx.remote.x.password.file : file name for default JAAS login configuration
+ * @return an Instance of REST adapter that allows to start/stop the adapter
+ */
+ public static synchronized JmxRestAdapter newRestAdapter(MBeanServer mbeanServer, String context, Map<String, ?> env) {
+ if (httpServer == null) {
+ throw new IllegalStateException("Platform Adapter not initialized");
+ }
+
+ MBeanServerResource server = restAdapters.stream()
+ .filter(s -> areMBeanServersEqual(s.getMBeanServer(), mbeanServer))
+ .findFirst()
+ .get();
+ if (server == null) {
+ MBeanServerResource adapter = new MBeanServerResource(httpServer, mbeanServer, context, env);
+ adapter.start();
+ restAdapters.add(adapter);
+ return adapter;
+ } else {
+ throw new IllegalArgumentException("MBeanServer already registered at " + server.getUrl());
+ }
+ }
+
+ private static boolean areMBeanServersEqual(MBeanServer server1, MBeanServer server2) {
+ MBeanServerDelegateMBean bean1 = JMX.newMBeanProxy(server1, MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
+ MBeanServerDelegateMBean bean2 = JMX.newMBeanProxy(server2, MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
+ return bean1.getMBeanServerId().equalsIgnoreCase(bean2.getMBeanServerId());
+ }
+
+ public synchronized static void stop() {
+ restAdapters.forEach(r -> r.stop());
+ restAdapters.clear();
+ if (httpServer != null) {
+ ExecutorService executor = (ExecutorService) httpServer.getExecutor();
+ executor.shutdownNow();
+ try {
+ executor.awaitTermination(30, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ }
+ httpServer.stop(0);
+ httpServer = null;
+ }
+ }
+
+ public static synchronized String getDomain() {
+ if (httpServer == null) {
+ throw new IllegalStateException("Platform rest adapter not initialized");
+ }
+ try {
+ if (httpServer instanceof HttpsServer) {
+ return "https://" + InetAddress.getLocalHost().getCanonicalHostName() + ":" + httpServer.getAddress().getPort();
+ }
+ return "http://" + InetAddress.getLocalHost().getCanonicalHostName() + ":" + httpServer.getAddress().getPort();
+ } catch (UnknownHostException ex) {
+ return "http://localhost" + ":" + httpServer.getAddress().getPort();
+ }
+ }
+
+ public static synchronized String getBaseURL() {
+ return getDomain() + "/jmx/servers";
+ }
+
+ private static SSLContext getSSlContext(String sslConfigFileName) {
+ final String keyStore, keyStorePassword, trustStore, trustStorePassword;
+
+ try {
+ if (sslConfigFileName == null || sslConfigFileName.isEmpty()) {
+ keyStore = System.getProperty(PropertyNames.SSL_KEYSTORE_FILE);
+ keyStorePassword = System.getProperty(PropertyNames.SSL_KEYSTORE_PASSWORD);
+ trustStore = System.getProperty(PropertyNames.SSL_TRUSTSTORE_FILE);
+ trustStorePassword = System.getProperty(PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+ } else {
+ Properties p = new Properties();
+ BufferedInputStream bin = new BufferedInputStream(new FileInputStream(sslConfigFileName));
+ p.load(bin);
+ keyStore = p.getProperty(PropertyNames.SSL_KEYSTORE_FILE);
+ keyStorePassword = p.getProperty(PropertyNames.SSL_KEYSTORE_PASSWORD);
+ trustStore = p.getProperty(PropertyNames.SSL_TRUSTSTORE_FILE);
+ trustStorePassword = p.getProperty(PropertyNames.SSL_TRUSTSTORE_PASSWORD);
+ }
+
+ char[] keyStorePasswd = null;
+ if (keyStorePassword.length() != 0) {
+ keyStorePasswd = keyStorePassword.toCharArray();
+ }
+
+ char[] trustStorePasswd = null;
+ if (trustStorePassword.length() != 0) {
+ trustStorePasswd = trustStorePassword.toCharArray();
+ }
+
+ KeyStore ks = null;
+ if (keyStore != null) {
+ ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ FileInputStream ksfis = new FileInputStream(keyStore);
+ ks.load(ksfis, keyStorePasswd);
+
+ }
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, keyStorePasswd);
+
+ KeyStore ts = null;
+ if (trustStore != null) {
+ ts = KeyStore.getInstance(KeyStore.getDefaultType());
+ FileInputStream tsfis = new FileInputStream(trustStore);
+ ts.load(tsfis, trustStorePasswd);
+ }
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+
+ SSLContext ctx = SSLContext.getInstance("SSL");
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ return ctx;
+ } catch (Exception ex) {
+ }
+ return null;
+ }
+
+ /**
+ * Default values for JMX configuration properties.
+ */
+ static interface DefaultValues {
+
+ public static final String PORT = "0";
+ public static final String HOST = "0.0.0.0";
+ public static final String USE_SSL = "false";
+ public static final String USE_AUTHENTICATION = "false";
+ public static final String PASSWORD_FILE_NAME = "jmxremote.password";
+ }
+
+ /**
+ * Names of JMX configuration properties.
+ */
+ public static interface PropertyNames {
+
+ public static final String PORT
+ = "com.sun.management.jmxremote.rest.port";
+ public static final String HOST
+ = "com.sun.management.jmxremote.host";
+ public static final String USE_SSL
+ = "com.sun.management.jmxremote.ssl";
+ public static final String SSL_CONFIG_FILE_NAME
+ = "com.sun.management.jmxremote.ssl.config.file";
+ public static final String SSL_KEYSTORE_FILE
+ = "javax.net.ssl.keyStore";
+ public static final String SSL_TRUSTSTORE_FILE
+ = "javax.net.ssl.trustStore";
+ public static final String SSL_KEYSTORE_PASSWORD
+ = "javax.net.ssl.keyStorePassword";
+ public static final String SSL_TRUSTSTORE_PASSWORD
+ = "javax.net.ssl.trustStorePassword";
+ public static final String USE_AUTHENTICATION
+ = "com.sun.management.jmxremote.authenticate";
+ public static final String PASSWORD_FILE_NAME
+ = "com.sun.management.jmxremote.password.file";
+ public static final String LOGIN_CONFIG_NAME
+ = "com.sun.management.jmxremote.login.config";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/RestAdapterProvider.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,44 @@
+package jdk.internal.management.remote.rest;
+
+import jdk.internal.agent.spi.AgentProvider;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class RestAdapterProvider extends AgentProvider {
+
+ private static final String REST_ADAPTER_NAME = "RestAdapter";
+
+ @Override
+ public synchronized void startAgent() {
+ try {
+ PlatformRestAdapter.init(null);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public synchronized void startAgent(Properties props) {
+ try {
+ PlatformRestAdapter.init(props);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public synchronized void stopAgent() {
+ PlatformRestAdapter.stop();
+ }
+
+ @Override
+ public String getName() {
+ return REST_ADAPTER_NAME;
+ }
+
+ @Override
+ public synchronized boolean isActive() {
+ return PlatformRestAdapter.isStarted();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/HttpResponse.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONObject;
+import jdk.internal.management.remote.rest.json.JSONPrimitive;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+
+/**
+ * Container class for standard HTTP reponses. Returns a JSON string for status
+ */
+public class HttpResponse {
+
+ public static final HttpResponse OK = new HttpResponse(HttpURLConnection.HTTP_OK, "Success");
+ public static final HttpResponse SERVER_ERROR = new HttpResponse(HttpURLConnection.HTTP_INTERNAL_ERROR, "Internal server error");
+ public static final HttpResponse METHOD_NOT_ALLOWED = new HttpResponse(HttpURLConnection.HTTP_BAD_METHOD, "Method not allowed");
+ public static final HttpResponse BAD_REQUEST = new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Bad request");
+ public static final HttpResponse REQUEST_NOT_FOUND = new HttpResponse(HttpURLConnection.HTTP_NOT_FOUND, "Request not found");
+
+ private final int code;
+ private final String message;
+ private final String body;
+
+ public HttpResponse(int code, String message) {
+ this(code, message, "");
+ }
+
+ public HttpResponse(String message) {
+ this(200,message,"");
+ }
+
+ public HttpResponse(int code, String message, String detail) {
+ this.code = code;
+ this.message = message;
+
+ if (code != HttpURLConnection.HTTP_OK) {
+ JSONObject jobj = new JSONObject();
+ jobj.put("status", new JSONPrimitive(code));
+ jobj.put("message", new JSONPrimitive(message));
+ if (detail != null && !detail.isEmpty()) {
+ jobj.put("details", new JSONPrimitive(detail));
+ }
+ this.body = jobj.toJsonString();
+ } else {
+ this.body = message;
+ }
+ }
+
+ public HttpResponse(HttpResponse response, String detail) {
+ this(response.code, response.message, detail);
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public static String getErrorMessage(Exception ex) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ ex.printStackTrace(pw);
+ return sw.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/HttpUtil.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONObject;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * A utility class for commonly used operations on {@link HttpExchange}
+ */
+public class HttpUtil {
+
+ public static String getRequestCharset(HttpExchange ex) {
+ String charset = null;
+ List<String> contentType = ex.getRequestHeaders().get("Content-type");
+ if (contentType != null) {
+ for (String kv : contentType) {
+ for (String value : kv.split(";")) {
+ value = value.trim();
+ if (value.toLowerCase().startsWith("charset=")) {
+ charset = value.substring("charset=".length());
+ }
+ }
+ }
+ }
+ return charset;
+ }
+
+ public static String getAcceptCharset(HttpExchange ex) {
+ List<String> acceptCharset = ex.getRequestHeaders().get("Accept-Charset");
+ if (acceptCharset != null && acceptCharset.size() > 0) {
+ return acceptCharset.get(0);
+ }
+ return null;
+ }
+
+ public static String getGetRequestResource(HttpExchange ex) throws UnsupportedEncodingException {
+ String charset = getRequestCharset(ex);
+ String httpHandlerPath = ex.getHttpContext().getPath();
+ String requestURIpath = ex.getRequestURI().getPath();
+ String getRequestPath = requestURIpath.substring(httpHandlerPath.length());
+ if (charset != null) {
+ return URLDecoder.decode(getRequestPath, charset);
+ } else {
+ return getRequestPath;
+ }
+ }
+
+ public static String getGetRequestQuery(HttpExchange ex) throws UnsupportedEncodingException {
+ String charset = getRequestCharset(ex);
+ String query = ex.getRequestURI().getQuery();
+ if (charset != null && query != null) {
+ return URLDecoder.decode(query, charset);
+ } else {
+ return query;
+ }
+ }
+
+ public static Map<String, String> getGetRequestQueryMap(HttpExchange ex)
+ throws UnsupportedEncodingException {
+ String query = ex.getRequestURI().getQuery();
+ Map<String, String> queryParams = new LinkedHashMap<>();
+
+ if (query == null || query.isEmpty()) {
+ return queryParams;
+ }
+ query = URLDecoder.decode(query, StandardCharsets.UTF_8.displayName());
+ String[] params = query.trim().split("&");
+ for (String param : params) {
+ int idx = param.indexOf('=');
+ if (idx != -1) {
+ queryParams.put(param.substring(0, idx), param.substring(idx + 1));
+ }
+ }
+ return queryParams;
+ }
+
+ public static String getCredentials(HttpExchange exchange) {
+ Headers rmap = exchange.getRequestHeaders();
+ String auth = rmap.getFirst("Authorization");
+ if (auth != null && !auth.isEmpty()) {
+ int sp = auth.indexOf(' ');
+ byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1));
+ String authCredentials = new String(b);
+ int colon = authCredentials.indexOf(':');
+ return authCredentials.substring(0, colon);
+ }
+ return "";
+ }
+
+ public static String readRequestBody(HttpExchange he) throws IOException {
+ String charset = getRequestCharset(he);
+ StringBuilder stringBuilder = new StringBuilder();
+ InputStreamReader in = charset != null ? new InputStreamReader(he.getRequestBody(), charset) : new InputStreamReader(he.getRequestBody());
+ BufferedReader br = new BufferedReader(in);
+ String line;
+ while ((line = br.readLine()) != null) {
+ String decode = charset != null ? URLDecoder.decode(line, charset) : line;
+ stringBuilder.append(decode);
+ }
+ return stringBuilder.toString();
+ }
+
+ public static void sendResponse(HttpExchange exchange, HttpResponse response) throws IOException {
+ String charset = getRequestCharset(exchange);
+ String acceptCharset = HttpUtil.getAcceptCharset(exchange);
+ if (acceptCharset != null) {
+ charset = acceptCharset;
+ }
+
+ // Set response headers explicitly
+ String msg = charset == null ? response.getBody() : URLEncoder.encode(response.getBody(), charset);
+ byte[] bytes = msg.getBytes();
+ Headers resHeaders = exchange.getResponseHeaders();
+ if (charset != null && !charset.isEmpty()) {
+ resHeaders.add("Content-Type", "application/json; charset=" + charset);
+ } else {
+ resHeaders.add("Content-Type", "application/json;");
+ }
+
+ exchange.sendResponseHeaders(response.getCode(), bytes.length);
+ try (OutputStream os = exchange.getResponseBody()) {
+ os.write(bytes);
+ }
+ }
+
+ public static <T> List<T> filterByPage(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
+
+ Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
+ int currPage = 1;
+ if (queryParams != null && !queryParams.isEmpty()) {
+ String pageStr = queryParams.get("page");
+ if (pageStr != null && !pageStr.isEmpty()) {
+ currPage = Integer.parseInt(pageStr);
+ currPage = currPage > 1 ? currPage : 1;
+ }
+ }
+
+ if (input.size() <= pageSize) {
+ return input;
+ }
+
+ int start = (currPage - 1) * pageSize;
+ int end = Math.min(input.size(), start + pageSize);
+ if (start < end) {
+ return input.subList(start, end);
+ } else {
+ return null;
+ }
+ }
+
+ public static <T> JSONObject getPaginationLinks(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException {
+
+ if (pageSize >= input.size()) {
+ return null;
+ }
+
+ Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange);
+ int currPage = 1;
+ if (queryParams != null && !queryParams.isEmpty()) {
+ String pageStr = queryParams.get("page");
+ if (pageStr != null && !pageStr.isEmpty()) {
+ currPage = Integer.parseInt(pageStr);
+ }
+ }
+ String path = PlatformRestAdapter.getDomain() + exchange.getRequestURI().getPath() + "?";
+ Map<String, String> queryMap = getGetRequestQueryMap(exchange);
+ if (queryMap != null) {
+ queryMap.remove("page");
+ if (!queryMap.isEmpty()) {
+ String query = queryMap.keySet().stream()
+ .map(k -> k + "=" + queryMap.get(k))
+ .collect(Collectors.joining("&"));
+ path = path + query + "&";
+ }
+ }
+ int totalPages = (input.size() % pageSize == 0) ? input.size() / pageSize : input.size() / pageSize + 1;
+
+ JSONObject jobj = new JSONObject();
+ jobj.put("first", path.replaceAll(".$", ""));
+ if (currPage == 2) {
+ jobj.put("prev", path.replaceAll(".$", ""));
+ } else if (currPage > 2) {
+ jobj.put("prev", path + "page=" + (currPage - 1));
+ }
+ if (currPage < totalPages) {
+ jobj.put("next", path + "page=" + (currPage + 1));
+ }
+ jobj.put("last", path + "page=" + totalPages);
+
+ return jobj;
+ }
+
+ public static String escapeUrl(String input) {
+ try {
+ URL url = new URL(input);
+ URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
+ return uri.toURL().toString();
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/MBeanCollectionResource.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONArray;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.JSONObject;
+import jdk.internal.management.remote.rest.json.JSONPrimitive;
+import jdk.internal.management.remote.rest.json.parser.JSONParser;
+import jdk.internal.management.remote.rest.json.parser.ParseException;
+import jdk.internal.management.remote.rest.mapper.JSONMapper;
+import jdk.internal.management.remote.rest.mapper.JSONMappingException;
+import jdk.internal.management.remote.rest.mapper.JSONMappingFactory;
+import com.sun.net.httpserver.HttpExchange;
+
+import javax.management.*;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+public class MBeanCollectionResource implements RestResource, NotificationListener {
+
+ private List<ObjectName> allowedMbeans;
+ private final MBeanServer mBeanServer;
+ private final Map<ObjectName, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>();
+ private static final int pageSize = 10;
+ private static final String pathPrefix = "^/?jmx/servers/[a-zA-Z0-9\\-\\.]+/mbeans";
+
+ // Only MXBean or any other MBean that uses types
+ // that have a valid mapper functions
+ private boolean isMBeanAllowed(ObjectName objName) {
+ try {
+ MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName);
+
+ // Return true for MXbean
+ Descriptor desc = mInfo.getDescriptor();
+ String isMxBean = (String) desc.getFieldValue("mxbean");
+ if (isMxBean != null && isMxBean.equalsIgnoreCase("true"))
+ return true;
+
+ // Check attribute types
+ MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes();
+ for (MBeanAttributeInfo attrInfo : attrsInfo) {
+ String type = attrInfo.getType();
+ if (!JSONMappingFactory.INSTANCE.isTypeMapped(type)) {
+ return false;
+ }
+ }
+
+ // Check operation parameters and return types
+ MBeanOperationInfo[] operations = mInfo.getOperations();
+ for (MBeanOperationInfo opInfo : operations) {
+ MBeanParameterInfo[] signature = opInfo.getSignature();
+ for (MBeanParameterInfo sig : signature) {
+ if (!JSONMappingFactory.INSTANCE.isTypeMapped(sig.getType())) {
+ return false;
+ }
+ }
+ if (!JSONMappingFactory.INSTANCE.isTypeMapped(opInfo.getReturnType())) {
+ return false;
+ }
+ }
+ return true;
+ } catch (InstanceNotFoundException | IntrospectionException |
+ ReflectionException | ClassNotFoundException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ private void introspectMBeanTypes(MBeanServer server) {
+ if (allowedMbeans.isEmpty()) {
+ Set<ObjectInstance> allMBeans = server.queryMBeans(null, null); // get all Mbeans
+ allMBeans.stream().filter((objIns) -> (isMBeanAllowed(objIns.getObjectName())))
+ .forEachOrdered(objIns -> allowedMbeans.add(objIns.getObjectName()));
+ }
+ }
+
+ @Override
+ public void handleNotification(Notification notification, Object handback) {
+ try {
+ MBeanServerNotification mbs = (MBeanServerNotification) notification;
+ if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+ ObjectName mBeanName = mbs.getMBeanName();
+ if (isMBeanAllowed(mBeanName)) {
+ allowedMbeans.add(mBeanName);
+ }
+ } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
+ if (allowedMbeans.contains(mbs.getMBeanName())) {
+ allowedMbeans.remove(mbs.getMBeanName());
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ public MBeanCollectionResource(MBeanServer mBeanServer) {
+ this.mBeanServer = mBeanServer;
+ allowedMbeans = new ArrayList<>();
+ introspectMBeanTypes(mBeanServer);
+ allowedMbeans = new CopyOnWriteArrayList<>(allowedMbeans);
+
+ // Create a REST handler for each MBean
+ allowedMbeans.forEach(objectName -> mBeanResourceMap.put(objectName,
+ new MBeanResource(mBeanServer, objectName)));
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.name());
+
+ if (path.matches(pathPrefix + "/?$")) {
+ RestResource.super.handle(exchange);
+ } else if (path.matches(pathPrefix + "/[^/]+/?.*")) {
+ // Extract mbean name
+ // Forward the request to its corresponding rest resource
+ Pattern mbeans = Pattern.compile(pathPrefix + "/");
+ Matcher matcher = mbeans.matcher(path);
+
+ if (matcher.find()) {
+ String ss = path.substring(matcher.end());
+ String mBeanName = ss;
+ if (ss.indexOf('/') != -1) {
+ mBeanName = ss.substring(0, ss.indexOf('/'));
+ }
+ try {
+ MBeanResource mBeanResource = mBeanResourceMap.get(new ObjectName(mBeanName));
+ if (mBeanResource == null) {
+ HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
+ return;
+ }
+ mBeanResource.handle(exchange);
+ } catch (MalformedObjectNameException e) {
+ HttpUtil.sendResponse(exchange, HttpResponse.BAD_REQUEST);
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public HttpResponse doGet(HttpExchange exchange) {
+ try {
+ final String path = PlatformRestAdapter.getDomain()
+ + URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName())
+ .replaceAll("/$", "");
+ List<ObjectName> filteredMBeans = allowedMbeans;
+ Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange);
+ String query = exchange.getRequestURI().getQuery();
+ if (query != null && queryMap.isEmpty()) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ "Invalid query params : Allowed query keys [objectname,page]");
+ } else if (query != null && !queryMap.isEmpty()) {
+ Map<String, String> newMap = new HashMap<>(queryMap);
+ newMap.remove("objectname");
+ newMap.remove("page");
+ if (!newMap.isEmpty()) { // Invalid query params
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ "Invalid query params : Allowed query keys [objectname,page]");
+ }
+ }
+ if (queryMap.containsKey("objectname")) { // Filter based on ObjectName query
+ Set<ObjectName> queryMBeans = mBeanServer
+ .queryNames(new ObjectName(queryMap.get("objectname")), null);
+ queryMBeans.retainAll(allowedMbeans); // Intersection of two lists
+ filteredMBeans = new ArrayList<>(queryMBeans);
+ }
+
+ JSONObject _links = HttpUtil.getPaginationLinks(exchange, filteredMBeans, pageSize);
+ List<ObjectName> mbeanPage = HttpUtil.filterByPage(exchange, filteredMBeans, pageSize);
+
+ List<Map<String, String>> items = new ArrayList<>(filteredMBeans.size());
+ for (ObjectName objectName : mbeanPage) {
+ Map<String, String> item = new LinkedHashMap<>();
+ item.put("name", objectName.getCanonicalName());
+ MBeanResource mBeanResource = mBeanResourceMap.get(objectName);
+ try {
+ JSONObject mBeanInfo = mBeanResource.getMBeanInfo(mBeanServer, objectName);
+ JSONElement element = mBeanInfo.get("descriptor");
+ if (element != null) {
+ JSONElement element1 = ((JSONObject) element).get("interfaceClassName");
+ if (element1 != null) {
+ String intfName = (String) ((JSONPrimitive) element1).getValue();
+ item.put("interfaceClassName", intfName);
+ }
+ }
+ element = mBeanInfo.get("className");
+ if (element != null) {
+ String className = (String) ((JSONPrimitive) element).getValue();
+ item.put("className", className);
+ }
+ element = mBeanInfo.get("description");
+ if (element != null) {
+ String description = (String) ((JSONPrimitive) element).getValue();
+ item.put("description", description);
+ }
+ element = mBeanInfo.get("attributeInfo");
+ if (element != null) {
+ item.put("attributeCount", ((JSONArray) element).size() + "");
+ }
+ element = mBeanInfo.get("operationInfo");
+ if (element != null) {
+ item.put("operationCount", ((JSONArray) element).size() + "");
+ }
+
+ } catch (InstanceNotFoundException | IntrospectionException | ReflectionException e) {
+ }
+
+ String href = path + "/" + objectName.toString();
+ href = HttpUtil.escapeUrl(href);
+ item.put("href", href);
+ items.add(item);
+ String info = HttpUtil.escapeUrl(href + "/info");
+ item.put("info", info);
+ }
+
+ Map<String, String> properties = new HashMap<>();
+
+ properties.put("mbeanCount", Integer.toString(filteredMBeans.size()));
+
+ JSONMapper typeMapper1 = JSONMappingFactory.INSTANCE.getTypeMapper(items);
+ JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties);
+
+ JSONElement linkElem = typeMapper1.toJsonValue(items);
+ JSONElement propElem = typeMapper2.toJsonValue(properties);
+ JSONObject jobj = new JSONObject();
+
+ jobj.putAll((JSONObject) propElem);
+ jobj.put("mbeans", linkElem);
+
+ if (_links != null && !_links.isEmpty()) {
+ jobj.put("_links", _links);
+ }
+ return new HttpResponse(jobj.toJsonString());
+ } catch (JSONMappingException e) {
+ return HttpResponse.SERVER_ERROR;
+ } catch (UnsupportedEncodingException e) {
+ return HttpResponse.BAD_REQUEST;
+ } catch (MalformedObjectNameException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
+ }
+ }
+
+ @Override
+ public HttpResponse doPost(HttpExchange exchange) {
+ try {
+ String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName());
+ String reqBody = null;
+ if (path.matches(pathPrefix + "/?$")) { // POST to current URL
+ reqBody = HttpUtil.readRequestBody(exchange);
+ if (reqBody == null || reqBody.isEmpty()) { // No Parameters
+ return HttpResponse.BAD_REQUEST;
+ }
+
+ JSONParser parser = new JSONParser(reqBody);
+ JSONElement jsonElement = parser.parse();
+ if (!(jsonElement instanceof JSONObject)) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ "Invalid parameters : [" + reqBody + "]");
+ }
+
+ JSONObject jsonObject = (JSONObject) jsonElement;
+ JSONObject normalizedObject = new JSONObject(jsonObject);
+
+ // Normalize the input MBean names
+ for (String objectNameString : jsonObject.keySet()) {
+ if (!objectNameString.startsWith("?")) { // Ignore object name patterns
+ JSONElement element = jsonObject.get(objectNameString);
+ normalizedObject.remove(objectNameString);
+ normalizedObject.put(new ObjectName(objectNameString).getCanonicalName(), element);
+ }
+ }
+
+ jsonObject.clear();
+ jsonObject = normalizedObject;
+
+ Set<String> objectNamePatterns = jsonObject.keySet()
+ .stream()
+ .filter(a -> a.startsWith("?"))
+ .collect(Collectors.toSet());
+
+ if (!objectNamePatterns.isEmpty()) {
+ for (String pattern : objectNamePatterns) {
+ Set<ObjectName> queryMBeans = mBeanServer
+ .queryNames(new ObjectName(pattern.substring(1)), null);
+ queryMBeans.retainAll(allowedMbeans);
+ JSONElement patternNode = jsonObject.get(pattern);
+ jsonObject.remove(pattern);
+ for (ObjectName queryMBean : queryMBeans) {
+ String name = queryMBean.getCanonicalName();
+ if (jsonObject.containsKey(name)) {
+ JSONObject obj = new JSONObject();
+ obj.put(name, patternNode);
+ deepMerge(jsonObject, obj);
+ } else {
+ jsonObject.put(name, patternNode);
+ }
+ }
+ }
+ }
+
+ JSONObject result = new JSONObject();
+ for (String mBeanName : jsonObject.keySet()) {
+ MBeanResource mBeanResource = mBeanResourceMap.get(new ObjectName(mBeanName));
+ if (mBeanResource != null) {
+ JSONElement element = jsonObject.get(mBeanName);
+ if (element instanceof JSONObject) {
+ JSONElement res = mBeanResource.handleBulkRequest
+ ((JSONObject) element);
+ result.put(mBeanName, res);
+ } else {
+ result.put(mBeanName, "Invalid input");
+ }
+ } else {
+ result.put(mBeanName, "Invalid MBean");
+ }
+ }
+ return new HttpResponse(result.toJsonString());
+ } else {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+ } catch (ParseException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid JSON String for request body");
+ } catch (IOException e) {
+ return HttpResponse.BAD_REQUEST;
+ } catch (MalformedObjectNameException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid query string");
+ }
+ }
+
+ private JSONObject deepMerge(JSONObject jsonObject1, JSONObject jsonObject2) {
+ for (String key : jsonObject2.keySet()) {
+ if (jsonObject1.containsKey(key)) {
+ if (jsonObject2.get(key) instanceof JSONObject && jsonObject1.get(key) instanceof JSONObject) {
+ JSONObject jobj1 = (JSONObject) jsonObject1.get(key);
+ JSONObject jobj2 = (JSONObject) jsonObject2.get(key);
+ jsonObject1.put(key, deepMerge(jobj1, jobj2));
+ } else if (jsonObject2.get(key) instanceof JSONArray && jsonObject1.get(key) instanceof JSONArray) {
+ JSONArray array1 = (JSONArray) jsonObject1.get(key);
+ JSONArray array2 = (JSONArray) jsonObject2.get(key);
+ for (JSONElement each : array2) {
+ if (!array1.contains(each)) {
+ array1.add(each);
+ }
+ }
+ } else {
+ JSONArray array = new JSONArray();
+ array.add(jsonObject1.get(key));
+ array.add(jsonObject2.get(key));
+ jsonObject1.put(key, array);
+ }
+ } else {
+ jsonObject1.put(key, jsonObject2.get(key));
+ }
+ }
+ return jsonObject1;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/MBeanResource.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONArray;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.JSONObject;
+import jdk.internal.management.remote.rest.json.JSONPrimitive;
+import jdk.internal.management.remote.rest.json.parser.JSONParser;
+import jdk.internal.management.remote.rest.json.parser.ParseException;
+import jdk.internal.management.remote.rest.json.parser.TokenMgrError;
+import jdk.internal.management.remote.rest.mapper.JSONDataException;
+import jdk.internal.management.remote.rest.mapper.JSONMapper;
+import jdk.internal.management.remote.rest.mapper.JSONMappingException;
+import jdk.internal.management.remote.rest.mapper.JSONMappingFactory;
+import com.sun.net.httpserver.HttpExchange;
+
+import javax.management.*;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenType;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static javax.management.MBeanOperationInfo.*;
+
+public class MBeanResource implements RestResource {
+
+ private final ObjectName objectName;
+ private final MBeanServer mBeanServer;
+ private static final String pathPrefix = "^/?jmx/servers/[^/]+/mbeans/[^/]+";
+
+ private final static Map<String, Class<?>> primitiveToObject = new HashMap<>();
+
+ static {
+ primitiveToObject.put("int", Integer.TYPE);
+ primitiveToObject.put("long", Long.TYPE);
+ primitiveToObject.put("double", Double.TYPE);
+ primitiveToObject.put("float", Float.TYPE);
+ primitiveToObject.put("boolean", Boolean.TYPE);
+ primitiveToObject.put("char", Character.TYPE);
+ primitiveToObject.put("byte", Byte.TYPE);
+ primitiveToObject.put("void", Void.TYPE);
+ primitiveToObject.put("short", Short.TYPE);
+ }
+
+ MBeanResource(MBeanServer mBeanServer, ObjectName objectName) {
+ this.mBeanServer = mBeanServer;
+ this.objectName = objectName;
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ String path = URLDecoder.decode(exchange.getRequestURI().getPath(),StandardCharsets.UTF_8.displayName());
+ if (path.matches(pathPrefix + "/?$")) {
+ RestResource.super.handle(exchange);
+ } else if (path.matches(pathPrefix + "/info$")
+ && exchange.getRequestMethod().equalsIgnoreCase("GET")) {
+ RestResource.super.handle(exchange);
+ } else if (path.matches(pathPrefix + "/[^/]+/?$")
+ && exchange.getRequestMethod().equalsIgnoreCase("POST")) {
+ RestResource.super.handle(exchange);
+ } else {
+ HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
+ }
+ }
+
+ @Override
+ public HttpResponse doGet(HttpExchange exchange) {
+ String path = PlatformRestAdapter.getDomain() +
+ exchange.getRequestURI().getPath().replaceAll("/$", "");
+
+ try {
+ path = URLDecoder.decode(path, StandardCharsets.UTF_8.displayName());
+ if (path.endsWith("info")) {
+ return doMBeanInfo();
+ }
+
+ String infoPath = path + "/info";
+
+ Map<String, Object> allAttributes = getAllAttributes();
+ Map<String, String> _links = new LinkedHashMap<>();
+ //_links.put("info", HttpUtil.escapeUrl(infoPath));
+
+ MBeanOperationInfo[] opInfo = mBeanServer.getMBeanInfo(objectName).getOperations();
+ JSONArray jarr = new JSONArray();
+ for (MBeanOperationInfo op : opInfo) {
+ JSONObject jobj1 = new JSONObject();
+ JSONArray jarr1 = new JSONArray();
+ jobj1.put("name", op.getName());
+ jobj1.put("href", HttpUtil.escapeUrl(path + "/" + op.getName()));
+ jobj1.put("method", "POST");
+ for (MBeanParameterInfo paramInfo : op.getSignature()) {
+ JSONObject jobj = new JSONObject();
+ jobj.put("name", paramInfo.getName());
+ jobj.put("type", paramInfo.getType());
+ jarr1.add(jobj);
+ }
+ jobj1.put("arguments", jarr1);
+ jobj1.put("returnType", op.getReturnType());
+ jarr.add(jobj1);
+ }
+
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(allAttributes);
+ if (typeMapper != null) {
+ JSONElement jsonElement1 = typeMapper.toJsonValue(allAttributes);
+ JSONElement jsonElement2 = typeMapper.toJsonValue(_links);
+
+ JSONObject jobj = new JSONObject();
+ jobj.put("attributes", jsonElement1);
+ jobj.put("operations", jarr);
+ return new HttpResponse(jobj.toJsonString());
+ } else {
+ return HttpResponse.SERVER_ERROR;
+ }
+ } catch (RuntimeOperationsException | IntrospectionException | ReflectionException
+ | JSONMappingException | MBeanException e) {
+ return HttpResponse.SERVER_ERROR;
+ } catch (InstanceNotFoundException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
+ } catch (Exception e) {
+ return HttpResponse.SERVER_ERROR;
+ }
+ }
+
+ /*
+ HTTP POST for this MBean's URL allows setting of attributes and execution of operations.
+ POST request body can follow one of the below formats
+ 1. { name : value}
+ Set a single attribute
+ 2. { name1 : value1, name2 : value2 }
+ Sets multiple attributes
+ 3. {attributes : {read : [name]} , {write : {name : value}}, operations : {op_name : {param_name:name, param_value:value}}}
+ This bulk operation request sets multiple attributes and executes multiple
+ operations on the MBean.
+ */
+ @Override
+ public HttpResponse doPost(HttpExchange exchange) {
+ String path = exchange.getRequestURI().getPath();
+ String reqBody = null;
+ try {
+ if (path.matches(pathPrefix + "/?$")) { // POST to current URL
+ reqBody = HttpUtil.readRequestBody(exchange);
+ if (reqBody.isEmpty()) { // No Parameters
+ return HttpResponse.BAD_REQUEST;
+ }
+
+ JSONParser parser = new JSONParser(reqBody);
+ JSONElement jsonElement = parser.parse();
+ if (!(jsonElement instanceof JSONObject)) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ "Invalid parameters : [" + reqBody + "]");
+ }
+
+ JSONObject jsonObject = (JSONObject) jsonElement;
+
+ // Handle bulk operation
+ if (jsonObject.keySet().contains("attributes") | jsonObject.keySet().contains("operations")) {
+ return new HttpResponse(handleBulkRequest(jsonObject).toJsonString());
+ } else { // Handle attribute update
+ Map<String, Object> stringObjectMap = setAttributes(jsonObject);
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(stringObjectMap);
+ if (typeMapper != null) {
+ return new HttpResponse(HttpURLConnection.HTTP_OK, typeMapper.toJsonValue(stringObjectMap).toJsonString());
+ } else {
+ return new HttpResponse(HttpResponse.SERVER_ERROR, "Unable to find JSON Mapper");
+ }
+ }
+ } else if (path.matches(pathPrefix + "/[^/]+/?$")) { // POST to MBeanOperation
+ Matcher matcher = Pattern.compile(pathPrefix + "/").matcher(path);
+ String operation;
+ if (matcher.find()) {
+ operation = path.substring(matcher.end());
+ } else {
+ return HttpResponse.BAD_REQUEST;
+ }
+
+ reqBody = HttpUtil.readRequestBody(exchange);
+ JSONElement result;
+ if (reqBody.isEmpty()) { // No Parameters
+ result = execOperation(operation, null);
+ } else {
+ JSONParser parser = new JSONParser(reqBody);
+ JSONElement jsonElement = parser.parse();
+ if (!(jsonElement instanceof JSONObject)) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ "Invalid parameters : [" + reqBody + "] for operation - " + operation);
+ }
+ result = execOperation(operation, (JSONObject) jsonElement);
+ }
+ return new HttpResponse(HttpURLConnection.HTTP_OK, result.toJsonString());
+ } else {
+ return HttpResponse.REQUEST_NOT_FOUND;
+ }
+ } catch (InstanceNotFoundException e) {
+ // Should never happen
+ } catch (JSONDataException | ParseException | TokenMgrError e) {
+ return new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid JSON : " + reqBody, e.getMessage());
+ } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException | IOException e) {
+ return HttpResponse.SERVER_ERROR;
+ } catch (IllegalArgumentException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, e.getMessage());
+ } catch (Exception e) {
+ return HttpResponse.SERVER_ERROR;
+ }
+ return HttpResponse.REQUEST_NOT_FOUND;
+ }
+
+ private HttpResponse doMBeanInfo() {
+ try {
+ JSONObject mBeanInfo = getMBeanInfo(mBeanServer, objectName);
+ return new HttpResponse(mBeanInfo.toJsonString());
+ } catch (RuntimeOperationsException | IntrospectionException | ReflectionException e) {
+ return HttpResponse.SERVER_ERROR;
+ } catch (InstanceNotFoundException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST, "Specified MBean does not exist");
+ } catch (Exception e) {
+ return HttpResponse.SERVER_ERROR;
+ }
+ }
+
+ JSONElement handleBulkRequest(JSONObject reqObject) {
+ JSONObject result = new JSONObject();
+
+ // Handle attributes
+ JSONElement element = reqObject.get("attributes");
+ if (element != null && element instanceof JSONObject) {
+ JSONObject attrInfo = (JSONObject) element;
+ JSONObject attrNode = new JSONObject();
+
+ // Read attributes
+ JSONElement read = attrInfo.get("get");
+ if (read != null) {
+ if (read instanceof JSONArray) {
+ JSONArray jsonAttrMap = (JSONArray) read;
+ JSONElement resultJson;
+ Map<String, Object> attrRead;
+ try {
+ String[] attributes = getStrings(jsonAttrMap);
+ attrRead = getAttributes(attributes);
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrRead);
+ resultJson = typeMapper.toJsonValue(attrRead);
+ } catch (InstanceNotFoundException | ReflectionException | JSONMappingException | MBeanException e) {
+ resultJson = new JSONPrimitive("<ERROR: Unable to retrieve value>");
+ } catch (JSONDataException e) {
+ resultJson = new JSONPrimitive("Invalid JSON : " + e.getMessage());
+ }
+ attrNode.put("get", resultJson);
+ } else {
+ attrInfo.put("get", new JSONPrimitive("Invalid JSON : " + read.toJsonString()));
+ }
+ }
+
+ // Write attributes
+ JSONElement write = attrInfo.get("set");
+
+ if (write != null) {
+ if (write instanceof JSONObject) {
+ JSONElement resultJson;
+ JSONObject jsonAttrMap = (JSONObject) write;
+ try {
+ Map<String, Object> attrMap = setAttributes(jsonAttrMap);
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrMap);
+ resultJson = typeMapper.toJsonValue(attrMap);
+ } catch (JSONDataException ex) {
+ resultJson = new JSONPrimitive("Invalid JSON : " + write.toJsonString());
+ } catch (JSONMappingException | IntrospectionException | InstanceNotFoundException | ReflectionException e) {
+ resultJson = new JSONPrimitive("<ERROR: Unable to retrieve value>");
+ }
+ attrNode.put("set", resultJson);
+ } else {
+ attrNode.put("set", new JSONPrimitive("Invalid JSON : " + write.toJsonString()));
+ }
+ }
+ result.put("attributes", attrNode);
+ }
+
+ // Execute operations
+ element = reqObject.get("operations");
+ if (element != null) {
+ JSONArray operationList;
+ if (element instanceof JSONPrimitive // Single no-arg operation
+ || element instanceof JSONObject) { // single/mulitple operations
+ operationList = new JSONArray();
+ operationList.add(element);
+ } else if (element instanceof JSONArray) { // List of no-arg/with-arg operation
+ operationList = (JSONArray) element;
+ } else {
+ operationList = new JSONArray();
+ }
+ JSONObject opResult = new JSONObject();
+ operationList.forEach((elem) -> {
+ if (elem instanceof JSONPrimitive
+ && ((JSONPrimitive) elem).getValue() instanceof String) { // no-arg operation
+ String opName = (String) ((JSONPrimitive) elem).getValue();
+ try {
+ JSONElement obj = execOperation(opName, null);
+ opResult.put(opName, obj);
+ } catch (IllegalArgumentException e) {
+ opResult.put(opName, e.getMessage());
+ } catch (IntrospectionException | InstanceNotFoundException
+ | MBeanException | ReflectionException e) {
+ opResult.put(opName, "<ERROR while executing operation>");
+ }
+ } else if (elem instanceof JSONObject) {
+ ((JSONObject) elem).keySet().forEach((opName) -> {
+ try {
+ JSONElement jsonElement = ((JSONObject) elem).get(opName);
+ if (jsonElement instanceof JSONObject) {
+ JSONElement obj = execOperation(opName, (JSONObject) jsonElement);
+ opResult.put(opName, obj);
+ } else {
+ opResult.put(opName, new JSONPrimitive("Invalid parameter JSON"));
+ }
+ } catch (IllegalArgumentException e) {
+ opResult.put(opName, e.getMessage());
+ } catch (IntrospectionException | InstanceNotFoundException
+ | MBeanException | ReflectionException e) {
+ opResult.put(opName, "<ERROR while executing operation>");
+ }
+ });
+ }
+ });
+ result.put("operations", opResult);
+ }
+ return result;
+ }
+
+ JSONObject getMBeanInfo(MBeanServer mbeanServer, ObjectName mbean)
+ throws InstanceNotFoundException, IntrospectionException, ReflectionException {
+
+ JSONObject jobj = new JSONObject();
+ MBeanInfo mBeanInfo = mbeanServer.getMBeanInfo(mbean);
+ if (mBeanInfo == null) {
+ return jobj;
+ }
+ jobj.put("name", mbean.getCanonicalName());
+ jobj.put("className", mBeanInfo.getClassName());
+ jobj.put("description", mBeanInfo.getDescription());
+
+ // Populate Attribute Info
+ MBeanAttributeInfo[] attributes = mBeanInfo.getAttributes();
+ JSONArray jarr = new JSONArray();
+ for (MBeanAttributeInfo attr : attributes) {
+ String access;
+ if (attr.isReadable()) {
+ if (attr.isWritable()) {
+ access = "read/write";
+ } else {
+ access = "read-only";
+ }
+ } else if (attr.isWritable()) {
+ access = "write-only";
+ } else {
+ access = "no-access";
+ }
+ JSONObject jobj1 = new JSONObject();
+ jobj1.put("name", attr.getName());
+ jobj1.put("type", attr.getType());
+ jobj1.put("access", access);
+ jobj1.put("description", attr.getDescription());
+ jobj1.put("descriptor", getDescriptorJSON(attr.getDescriptor()));
+ jarr.add(jobj1);
+ }
+ jobj.put("attributeInfo", jarr);
+
+
+ // Add constructor Info
+ MBeanConstructorInfo[] constructorInfo = mBeanInfo.getConstructors();
+ jarr = new JSONArray();
+ for (MBeanConstructorInfo constructor : constructorInfo) {
+ JSONObject jobj1 = new JSONObject();
+ jobj1.put("name", constructor.getName());
+ JSONArray jarr1 = new JSONArray();
+ for (MBeanParameterInfo paramInfo : constructor.getSignature()) {
+ jarr1.add(getParamJSON(paramInfo));
+ }
+ jobj1.put("signature", jarr1);
+ jobj1.put("description", constructor.getDescription());
+ if (constructor.getDescriptor().getFieldNames().length > 1) {
+ jobj1.put("descriptor", getDescriptorJSON(constructor.getDescriptor()));
+ }
+ jarr.add(jobj1);
+ }
+ jobj.put("constructorInfo", jarr);
+
+ MBeanOperationInfo[] opInfo = mBeanInfo.getOperations();
+ jarr = new JSONArray();
+
+ for (MBeanOperationInfo op : opInfo) {
+ String impactString;
+ switch (op.getImpact()) {
+ case ACTION:
+ impactString = "action";
+ break;
+ case ACTION_INFO:
+ impactString = "action/info";
+ break;
+ case INFO:
+ impactString = "info";
+ break;
+ case UNKNOWN:
+ impactString = "unknown";
+ break;
+ default:
+ impactString = "(" + op.getImpact() + ")";
+ }
+
+ JSONObject jobj1 = new JSONObject();
+
+ jobj1.put("name", op.getName());
+ JSONArray jarr1 = new JSONArray();
+ for (MBeanParameterInfo paramInfo : op.getSignature()) {
+ jarr1.add(getParamJSON(paramInfo));
+ }
+ jobj1.put("signature", jarr1);
+ jobj1.put("returnType", op.getReturnType());
+ jobj1.put("impact", impactString);
+ jobj1.put("description", op.getDescription());
+ if (op.getDescriptor().getFieldNames().length > 1) {
+ jobj1.put("descriptor", getDescriptorJSON(op.getDescriptor()));
+ }
+ jarr.add(jobj1);
+ }
+ jobj.put("operationInfo", jarr);
+
+ MBeanNotificationInfo[] notifications = mBeanInfo.getNotifications();
+ jarr = new JSONArray();
+
+ for (MBeanNotificationInfo notification : notifications) {
+ JSONObject jobj1 = new JSONObject();
+ jobj1.put("name", notification.getName());
+ JSONArray jarr1 = new JSONArray();
+ for (String notifType : notification.getNotifTypes()) {
+ jarr1.add(new JSONPrimitive(notifType));
+ }
+ jobj1.put("notifTypes", jarr1);
+ jobj1.put("description", notification.getDescription());
+ if (notification.getDescriptor().getFieldNames().length > 1) {
+ jobj1.put("descriptor", getDescriptorJSON(notification.getDescriptor()));
+ }
+ jarr.add(jobj1);
+ }
+ jobj.put("notificationInfo", jarr);
+
+ jobj.put("descriptor", getDescriptorJSON(mBeanInfo.getDescriptor()));
+ return jobj;
+ }
+
+ private JSONObject getParamJSON(MBeanParameterInfo mParamInfo) {
+ JSONObject jobj1 = new JSONObject();
+ jobj1.put("name", mParamInfo.getName());
+ jobj1.put("type", mParamInfo.getType());
+ if (mParamInfo.getDescription() != null && !mParamInfo.getDescription().isEmpty()) {
+ jobj1.put("description", mParamInfo.getDescription());
+ }
+ if (mParamInfo.getDescriptor() != null && mParamInfo.getDescriptor().getFieldNames().length > 1) {
+ jobj1.put("descriptor", getDescriptorJSON(mParamInfo.getDescriptor()));
+ }
+ return jobj1;
+ }
+
+ private JSONObject getDescriptorJSON(Descriptor descriptor) {
+ JSONObject jobj2 = new JSONObject();
+ String[] descNames = descriptor.getFieldNames();
+ for (String descName : descNames) {
+ Object fieldValue = descriptor.getFieldValue(descName);
+ jobj2.put(descName, fieldValue != null ? fieldValue.toString() : null);
+ }
+ return jobj2;
+ }
+
+ private Map<String, Object> getAttributes(String[] attrs) throws
+ InstanceNotFoundException, ReflectionException, MBeanException {
+
+ Map<String, Object> result = new LinkedHashMap<>();
+
+ if (attrs == null || attrs.length == 0) {
+ return result;
+ }
+
+ AttributeList attrVals = mBeanServer.getAttributes(objectName, attrs);
+ List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
+ attrVals.asList().forEach(a -> {
+ missingAttrs.remove(a.getName());
+ result.put(a.getName(), a.getValue());
+ });
+
+ for (String attr : missingAttrs) {
+ try {
+ mBeanServer.getAttribute(objectName, attr);
+ result.put(attr, "< Error: No such attribute >");
+ } catch (RuntimeException ex) {
+ if (ex.getCause() instanceof UnsupportedOperationException) {
+ result.put(attr, "< Attribute not supported >");
+ } else if (ex.getCause() instanceof IllegalArgumentException) {
+ result.put(attr, "< Invalid attributes >");
+ }
+ } catch (AttributeNotFoundException e) {
+ result.put(attr, "< Attribute not found >");
+ }
+ }
+ return result;
+ }
+
+ private Map<String, Object> getAllAttributes() throws InstanceNotFoundException,
+ ReflectionException, MBeanException, IntrospectionException {
+
+ MBeanInfo mInfo = mBeanServer.getMBeanInfo(objectName);
+ String[] attrs = Stream.of(mInfo.getAttributes())
+ .map(MBeanAttributeInfo::getName)
+ .toArray(String[]::new);
+
+ return getAttributes(attrs);
+ }
+
+ private Map<String, Object> setAttributes(JSONObject attrMap) throws JSONDataException,
+ IntrospectionException, InstanceNotFoundException, ReflectionException {
+
+ if (attrMap == null || attrMap.isEmpty()) {
+ throw new JSONDataException("Null arguments for set attribute");
+ }
+
+ MBeanInfo mBeanInfo = mBeanServer.getMBeanInfo(objectName);
+ Map<String, Object> result = new HashMap<>();
+
+ for (String attrName : attrMap.keySet()) {
+ MBeanAttributeInfo attrInfo = Arrays.stream(mBeanInfo.getAttributes()).
+ filter(a -> a.getName().equals(attrName)).findFirst().orElse(null);
+ if (attrInfo == null) {
+ result.put(attrName, "<Attribute not found>");
+ } else if (!attrInfo.isWritable()) {
+ result.put(attrName, "<Attribute is read-only>");
+ } else {
+ JSONMapper mapper;
+ if (attrInfo instanceof OpenMBeanAttributeInfo) {
+ OpenType<?> type = ((OpenMBeanAttributeInfo) attrInfo).getOpenType();
+ mapper = JSONMappingFactory.INSTANCE.getTypeMapper(type);
+ } else {
+ Class<?> inputCls = primitiveToObject.get(attrInfo.getType());
+ try {
+ if (inputCls == null) {
+ inputCls = Class.forName(attrInfo.getType());
+ }
+ } catch (ClassNotFoundException | ClassCastException ex) {
+ throw new IllegalArgumentException("Invalid parameters : "
+ + attrMap.get(attrName).toJsonString() + " cannot be mapped to : " + attrInfo.getType());
+ }
+ mapper = JSONMappingFactory.INSTANCE.getTypeMapper(inputCls);
+ }
+ try {
+ Object attrValue = mapper.toJavaObject(attrMap.get(attrName));
+ Attribute attrObj = new Attribute(attrName, attrValue);
+ mBeanServer.setAttribute(objectName, attrObj);
+ result.put(attrName, "success");
+ } catch (InvalidAttributeValueException | JSONDataException e) {
+ result.put(attrName, "<Invalid value for the attribute>");
+ } catch (AttributeNotFoundException e) {
+ result.put(attrName, "<Attribute not found>");
+ } catch (ReflectionException | InstanceNotFoundException | MBeanException e) {
+ result.put(attrName, "<ERROR: Unable to retrieve value>");
+ }
+ }
+ }
+ return result;
+ }
+
+ private Object mapJsonElemToType(JSONElement jsonElement, MBeanParameterInfo type) {
+ if (type instanceof OpenMBeanParameterInfo) {
+ OpenType<?> openType = ((OpenMBeanParameterInfo) type).getOpenType();
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(openType);
+ try {
+ return typeMapper.toJavaObject(jsonElement);
+ } catch (JSONDataException ex) {
+ throw new IllegalArgumentException("Invalid JSON String : " + jsonElement.toJsonString() + " for arguments");
+ }
+ } else {
+ Class<?> inputCls = primitiveToObject.get(type.getType());
+ try {
+ if (inputCls == null) {
+ inputCls = Class.forName(type.getType());
+ }
+ } catch (ClassNotFoundException | ClassCastException ex) {
+ throw new IllegalArgumentException("Invalid parameters : " + jsonElement.toJsonString() + " cannot be mapped to : " + type.getType());
+ }
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(inputCls);
+ if (typeMapper == null) {
+ throw new IllegalArgumentException("Invalid parameters : " + jsonElement.toJsonString() + " cannot be mapped to : " + type.getType());
+ }
+ try {
+ return typeMapper.toJavaObject(jsonElement);
+ } catch (JSONDataException ex) {
+ throw new IllegalArgumentException("Invalid JSON String : " + jsonElement.toJsonString() + " for arguments");
+ }
+ }
+ }
+
+ private Map<String, Object> getOperationParameters(Map<String, JSONElement> jsonValues, Map<String, MBeanParameterInfo> typeMap) {
+ if (jsonValues.size() != typeMap.size()) {
+ throw new IllegalArgumentException("Invalid parameters : expected - " + typeMap.size() + " parameters, got - " + jsonValues.size());
+ }
+ if (!jsonValues.keySet().equals(typeMap.keySet())) {
+ throw new IllegalArgumentException("Invalid parameters - expected : " + Arrays.toString(typeMap.keySet().toArray()));
+ }
+ Map<String, Object> parameters = new LinkedHashMap<>(); // Order of parameters should be same as typeMap
+ if (typeMap.isEmpty() && jsonValues.isEmpty()) {
+ return parameters;
+ }
+ typeMap.keySet().forEach((name) -> {
+ MBeanParameterInfo type = typeMap.get(name);
+ JSONElement jsonVal = jsonValues.get(name);
+ Object obj = mapJsonElemToType(jsonVal, type);
+ parameters.put(name, obj);
+ });
+ return parameters;
+ }
+
+ private JSONElement execOperation(String opstr, JSONObject params)
+ throws MBeanException, IntrospectionException, ReflectionException, InstanceNotFoundException {
+ if (params == null) {
+ params = new JSONObject();
+ }
+ MBeanInfo mBeanInfo;
+ try {
+ mBeanInfo = mBeanServer.getMBeanInfo(objectName);
+ } catch (InstanceNotFoundException ex) {
+ throw new IllegalArgumentException("MBean does not exist");
+ }
+
+ List<MBeanOperationInfo> mBeanOperationInfos = Arrays.stream(mBeanInfo.getOperations()).
+ filter(a -> a.getName().equals(opstr)).collect(Collectors.toList());
+
+ if (mBeanOperationInfos.isEmpty()) {
+ throw new IllegalArgumentException("Invalid Operation String");
+ }
+
+ String[] signature = null;
+ Object[] parameters = null;
+
+ IllegalArgumentException exception = null;
+ for (MBeanOperationInfo mBeanOperationInfo : mBeanOperationInfos) {
+ MBeanParameterInfo[] sig = mBeanOperationInfo.getSignature();
+ try {
+ Map<String, MBeanParameterInfo> typeMap = new LinkedHashMap<>(); // Order of parameters is important
+ Arrays.stream(sig).forEach(e -> typeMap.put(e.getName(), e));
+ parameters = getOperationParameters(params, typeMap).values().toArray();
+ signature = Stream.of(sig).map(MBeanParameterInfo::getType).toArray(String[]::new);
+ exception = null;
+ break;
+ } catch (IllegalArgumentException ex) {
+ exception = ex;
+ }
+ }
+ if (exception != null) {
+ throw exception;
+ }
+
+ Object invoke;
+ try {
+ invoke = mBeanServer.invoke(objectName, opstr, parameters, signature);
+ if (invoke != null) {
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(invoke);
+ if (typeMapper != null) {
+ return typeMapper.toJsonValue(invoke);
+ } else {
+ return new JSONPrimitive("<Unable to map result to JSON>");
+ }
+ } else {
+ return new JSONPrimitive("void");
+ }
+ } catch (JSONMappingException e) {
+ return new JSONPrimitive("<Unable to map result to JSON>");
+ }
+ }
+
+ private String[] getStrings(JSONArray jsonArray) throws JSONDataException {
+ List<String> attributes = new ArrayList<>();
+ for (JSONElement element : jsonArray) {
+ if (element instanceof JSONPrimitive && ((JSONPrimitive) element).getValue() instanceof String) {
+ JSONPrimitive val = (JSONPrimitive) element;
+ attributes.add((String) val.getValue());
+ } else throw new JSONDataException("Expecting String, got " + element.toJsonString());
+ }
+ return attributes.toArray(new String[0]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/MBeanServerCollectionResource.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONArray;
+import jdk.internal.management.remote.rest.json.JSONObject;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
+
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * This class handles all the HTTP requests for the base URL
+ * for REST adapter.
+ */
+public class MBeanServerCollectionResource implements RestResource {
+
+ private final List<MBeanServerResource> restAdapters;
+ private final int pageSize = 5;
+
+ public MBeanServerCollectionResource(List<MBeanServerResource> adapters, HttpServer server) {
+ this.restAdapters = adapters;
+ server.createContext("/jmx/servers", this);
+ }
+
+ @Override
+ public HttpResponse doGet(HttpExchange exchange) {
+ try {
+ JSONObject _links = HttpUtil.getPaginationLinks(exchange, restAdapters, pageSize);
+ List<MBeanServerResource> filteredList = HttpUtil.filterByPage(exchange, restAdapters, pageSize);
+ if (filteredList == null) {
+ return HttpResponse.OK;
+ }
+ String query = exchange.getRequestURI().getQuery();
+ if (query != null) {
+ return HttpResponse.BAD_REQUEST;
+ }
+ String exchangePath = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName())
+ .replaceAll("/$", "");
+ if (!exchangePath.equalsIgnoreCase("/jmx/servers")) {
+ return HttpResponse.REQUEST_NOT_FOUND;
+ }
+ final String path = PlatformRestAdapter.getDomain() + exchangePath;
+
+ JSONObject root = new JSONObject();
+ if (_links != null && !_links.isEmpty()) {
+ root.put("_links", _links);
+ }
+
+ root.put("mBeanServerCount", Integer.toString(restAdapters.size()));
+
+ JSONArray list = new JSONArray();
+ filteredList.stream().map((adapter) -> {
+ JSONObject result = new JSONObject();
+ result.put("name", adapter.getContext());
+ result.put("href", path + "/" + adapter.getContext());
+ return result;
+ }).forEachOrdered((result) -> {
+ list.add(result);
+ });
+ root.put("mBeanServers", list);
+ return new HttpResponse(HttpURLConnection.HTTP_OK, root.toJsonString());
+ } catch (UnsupportedEncodingException e) {
+ return new HttpResponse(HttpResponse.BAD_REQUEST,
+ HttpUtil.getRequestCharset(exchange) + " is not supported");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/MBeanServerResource.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.mapper.JSONMapper;
+import jdk.internal.management.remote.rest.mapper.JSONMappingException;
+import jdk.internal.management.remote.rest.mapper.JSONMappingFactory;
+import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
+import com.sun.jmx.remote.security.SubjectDelegator;
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerDelegateMBean;
+import javax.management.remote.JMXAuthenticator;
+import jdk.internal.management.remote.rest.JmxRestAdapter;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
+
+import javax.security.auth.Subject;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+public final class MBeanServerResource implements RestResource, JmxRestAdapter {
+
+ // Initialization parameters
+ private final HttpServer httpServer;
+ private final String contextStr;
+ private final Map<String, ?> env;
+ private final MBeanServer mbeanServer;
+
+ // Save the context to start/stop the adapter
+ private HttpContext httpContext;
+ private JMXAuthenticator authenticator = null;
+ private final MBeanServerDelegateMBean mBeanServerDelegateMBean;
+
+ // Save MBeanServer Proxy for a user
+ private final MBeanCollectionResource defaultMBeansResource;
+ // Use an expiring map that removes entries after the configured period lapses.
+ private final TimedMap<String, MBeanCollectionResource> proxyMBeanServers = new TimedMap<>(5*60);
+
+ private static AtomicInteger resourceNumber = new AtomicInteger(1);
+ private boolean started = false;
+
+ public MBeanServerResource(HttpServer hServer, MBeanServer mbeanServer,
+ String context, Map<String, ?> env) {
+ this.httpServer = hServer;
+ this.env = env;
+ this.mbeanServer = mbeanServer;
+
+ mBeanServerDelegateMBean = JMX.newMBeanProxy(mbeanServer,
+ MBeanServerDelegate.DELEGATE_NAME, MBeanServerDelegateMBean.class);
+
+ if (context == null || context.isEmpty()) {
+ contextStr = "server-" + resourceNumber.getAndIncrement();
+ } else {
+ contextStr = context;
+ }
+ // setup authentication
+ if (env.get("jmx.remote.x.authentication") != null) {
+ authenticator = (JMXAuthenticator) env.get("jmx.remote.authenticator");
+ if (authenticator == null) {
+ if (env.get("jmx.remote.x.password.file") != null
+ || env.get("jmx.remote.x.login.config") != null) {
+ authenticator = new JMXPluggableAuthenticator(env);
+ } else {
+ throw new IllegalArgumentException
+ ("Config error : Authentication is enabled with no authenticator");
+ }
+ }
+ }
+
+ if (env.get("jmx.remote.x.authentication") == null) {
+ defaultMBeansResource = new MBeanCollectionResource(mbeanServer);
+ } else {
+ defaultMBeansResource = null;
+ }
+ }
+
+ private MBeanServer getMBeanServerProxy(MBeanServer mbeaServer, Subject subject) {
+ return (MBeanServer) Proxy.newProxyInstance(MBeanServer.class.getClassLoader(),
+ new Class<?>[]{MBeanServer.class},
+ new AuthInvocationHandler(mbeaServer, subject));
+ }
+
+ @Override
+ public HttpResponse doGet(HttpExchange exchange) {
+ String selfUrl = getUrl();
+ Map<String, String> links = new LinkedHashMap<>();
+ links.put("mbeans", selfUrl + "/mbeans");
+
+ Map<String, Object> mBeanServerInfo = getMBeanServerInfo();
+ mBeanServerInfo.put("_links", links);
+
+ final JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(mBeanServerInfo);
+ if (typeMapper != null) {
+ try {
+ JSONElement jsonElement = typeMapper.toJsonValue(mBeanServerInfo);
+ return new HttpResponse(jsonElement.toJsonString());
+ } catch (JSONMappingException e) {
+ return HttpResponse.SERVER_ERROR;
+ }
+ } else {
+ return HttpResponse.SERVER_ERROR;
+ }
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ MBeanCollectionResource mBeansResource = defaultMBeansResource;
+ if (env.get("jmx.remote.x.authentication") != null) {
+ String authCredentials = HttpUtil.getCredentials(exchange);
+ // MBeanServer proxy should be populated in the authenticator
+ mBeansResource = proxyMBeanServers.get(authCredentials);
+ if (mBeansResource == null) {
+ throw new IllegalArgumentException("Invalid HTTP request Headers");
+ }
+ }
+
+ String path = URLDecoder.decode(exchange.getRequestURI().getPath(), StandardCharsets.UTF_8.displayName());
+ String pathPrefix = httpContext.getPath();
+ // Route request to appropriate resource
+ if (path.matches(pathPrefix + "/?$")) {
+ RestResource.super.handle(exchange);
+ } else if (path.matches(pathPrefix + "/mbeans.*")) {
+ mBeansResource.handle(exchange);
+ } else {
+ HttpUtil.sendResponse(exchange, HttpResponse.REQUEST_NOT_FOUND);
+ }
+ }
+
+ @Override
+ public synchronized void start() {
+ if (!started) {
+ httpContext = httpServer.createContext("/jmx/servers/" + contextStr, this);
+ if (env.get("jmx.remote.x.authentication") != null) {
+ httpContext.setAuthenticator(new RestAuthenticator("jmx-rest"));
+ }
+ started = true;
+ }
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (!started) {
+ throw new IllegalStateException("Rest Adapter not started yet");
+ }
+ httpServer.removeContext(httpContext);
+ started = false;
+ }
+
+ @Override
+ public String getUrl() {
+ return PlatformRestAdapter.getBaseURL() + "/" + contextStr;
+ }
+
+ @Override
+ public MBeanServer getMBeanServer() {
+ return mbeanServer;
+ }
+
+ public String getContext() {
+ return contextStr;
+ }
+
+ private class RestAuthenticator extends BasicAuthenticator {
+
+ RestAuthenticator(String realm) {
+ super(realm);
+ }
+
+ @Override
+ public boolean checkCredentials(String username, String password) {
+ if (proxyMBeanServers.containsKey(username)) {
+ return true;
+ } else {
+ Subject subject = null;
+ if (authenticator != null) {
+ String[] credential = new String[]{username, password};
+ try {
+ subject = authenticator.authenticate(credential);
+ } catch (SecurityException e) {
+ return false;
+ }
+ }
+ MBeanServer proxy = getMBeanServerProxy(mbeanServer, subject);
+ proxyMBeanServers.put(username, new MBeanCollectionResource(proxy));
+ return true;
+ }
+ }
+ }
+
+ Map<String, Object> getMBeanServerInfo() {
+ Map<String, Object> result = new LinkedHashMap<>();
+
+ result.put("id", mBeanServerDelegateMBean.getMBeanServerId());
+ result.put("context", contextStr);
+
+ result.put("defaultDomain", mbeanServer.getDefaultDomain());
+ result.put("mBeanCount", mbeanServer.getMBeanCount());
+ result.put("domains", Arrays.toString(mbeanServer.getDomains()));
+
+ result.put("specName", mBeanServerDelegateMBean.getSpecificationName());
+ result.put("specVersion", mBeanServerDelegateMBean.getSpecificationVersion());
+ result.put("specVendor", mBeanServerDelegateMBean.getSpecificationVendor());
+
+ result.put("implName", mBeanServerDelegateMBean.getImplementationName());
+ result.put("implVersion", mBeanServerDelegateMBean.getImplementationVersion());
+ result.put("implVendor", mBeanServerDelegateMBean.getImplementationVendor());
+
+ return result;
+ }
+
+ private class AuthInvocationHandler implements InvocationHandler {
+
+ private final MBeanServer mbeanServer;
+ private final AccessControlContext acc;
+
+ AuthInvocationHandler(MBeanServer server, Subject subject) {
+ this.mbeanServer = server;
+ if (subject == null) {
+ this.acc = null;
+ } else {
+ if (SubjectDelegator.checkRemoveCallerContext(subject)) {
+ acc = JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
+ } else {
+ acc = JMXSubjectDomainCombiner.getContext(subject);
+ }
+ }
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (acc == null) {
+ return method.invoke(mbeanServer, args);
+ } else {
+ PrivilegedAction<Object> op = () -> {
+ try {
+ return method.invoke(mbeanServer, args);
+ } catch (Exception ex) {
+ }
+ return null;
+ };
+ return AccessController.doPrivileged(op, acc);
+ }
+ }
+ }
+
+ /*
+ This is an expiring map that removes entries after the configured time period lapses.
+ This is required to re-authenticate the user after the timeout.
+ */
+ private class TimedMap<K,V> {
+
+ private ConcurrentHashMap<K,TimeStampedValue<V>> permanentMap;
+ private long timeout = Long.MAX_VALUE; // Timeout in seconds
+
+ private class TimeStampedValue<T> {
+ private final T value;
+ private final long insertTimeStamp;
+
+ TimeStampedValue(T value) {
+ this.value = value;
+ insertTimeStamp = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
+ }
+ }
+
+ public TimedMap(int seconds) {
+ this.timeout = seconds;
+ permanentMap = new ConcurrentHashMap<>();
+ }
+
+ public boolean containsKey(K key) {
+ return permanentMap.containsKey(key);
+ }
+
+ public V get(K key) {
+ TimeStampedValue<V> vTimeStampedValue = permanentMap.get(key);
+ long current = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
+ if(current - vTimeStampedValue.insertTimeStamp > timeout) {
+ permanentMap.remove(key);
+ return null;
+ } else {
+ return vTimeStampedValue.value;
+ }
+ }
+
+ public void put(K key, V value) {
+ permanentMap.put(key, new TimeStampedValue<>(value));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/http/RestResource.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.http;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author harsha
+ */
+public interface RestResource extends HttpHandler {
+ @Override
+ public default void handle(HttpExchange exchange) throws IOException {
+ HttpResponse httpResponse = HttpResponse.METHOD_NOT_ALLOWED;
+ switch (exchange.getRequestMethod()) {
+ case "GET":
+ httpResponse = doGet(exchange);
+ break;
+ case "POST":
+ httpResponse = doPost(exchange);
+ break;
+ case "PUT":
+ httpResponse = doPut(exchange);
+ break;
+ case "DELETE":
+ httpResponse = doDelete(exchange);
+ break;
+ case "HEAD":
+ httpResponse = doHead(exchange);
+ break;
+ case "PATCH":
+ httpResponse = doPatch(exchange);
+ break;
+ case "CONNET":
+ httpResponse = doConnect(exchange);
+ break;
+ case "TRACE":
+ httpResponse = doTrace(exchange);
+ break;
+ case "OPTIONS":
+ httpResponse = doOptions(exchange);
+ break;
+ }
+ HttpUtil.sendResponse(exchange, httpResponse);
+ }
+
+ public default HttpResponse doGet(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doPut(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doPost(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doDelete(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doHead(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doConnect(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doOptions(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doTrace(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+
+ public default HttpResponse doPatch(HttpExchange exchange) {
+ return HttpResponse.METHOD_NOT_ALLOWED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/JSONArray.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.json;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author harsha
+ */
+public class JSONArray extends ArrayList<JSONElement> implements JSONElement {
+
+ private static final long serialVersionUID = -506975558678956426L;
+
+ @Override
+ public String toJsonString() {
+ if (isEmpty()) {
+ return null;
+ }
+ StringBuilder sbuild = new StringBuilder();
+ sbuild.append("[");
+ Iterator<JSONElement> itr = iterator();
+ while (itr.hasNext()) {
+ JSONElement val = itr.next();
+ if (val != null)
+ sbuild.append(val.toJsonString()).append(", ");
+ else
+ sbuild.append("null").append(", ");
+ }
+
+ sbuild.deleteCharAt(sbuild.lastIndexOf(","));
+ sbuild.append("]");
+ return sbuild.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/JSONElement.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.json;
+
+/**
+ * @author harsha
+ */
+public interface JSONElement {
+ public String toJsonString();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/JSONObject.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.json;
+
+import java.util.LinkedHashMap;
+
+/**
+ * @author harsha
+ */
+public class JSONObject extends LinkedHashMap<String, JSONElement> implements JSONElement {
+
+ private static final long serialVersionUID = -9148596129640441014L;
+
+ public JSONObject() {
+ super();
+ }
+
+ public JSONObject(JSONObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public JSONElement put(String key, String value) {
+ return super.put(key, new JSONPrimitive(value));
+ }
+
+ @Override
+ public String toJsonString() {
+ if (isEmpty()) {
+ return null;
+ }
+
+ StringBuilder sbuild = new StringBuilder();
+ sbuild.append("{");
+ keySet().forEach((s) -> {
+ sbuild.append("\"").append(s).append("\"").append(": ").
+ append((get(s) != null) ? get(s).toJsonString() : "null").append(",");
+ });
+
+ sbuild.deleteCharAt(sbuild.lastIndexOf(","));
+ sbuild.append("}");
+ return sbuild.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/JSONPrimitive.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.json;
+
+/**
+ * @author harsha
+ */
+public class JSONPrimitive implements JSONElement {
+
+ private final Object value;
+
+ public JSONPrimitive(long i) {
+ value = i;
+ }
+
+ public JSONPrimitive(double i) {
+ value = i;
+ }
+
+ public JSONPrimitive(Boolean i) {
+ value = i;
+ }
+
+ public JSONPrimitive(String s) {
+ value = s;
+ }
+
+ public static String escape(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ if (ch == '\\') {
+ if (i < s.length() - 1 && (s.charAt(i + 1) == '\\' || s.charAt(i + 1) == '"')) {
+ sb.append(ch).append(s.charAt(i + 1));
+ i++;
+ } else {
+ sb.append("\\\\");
+ }
+ } else if (ch == '"') {
+ sb.append("\\\"");
+ } else {
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public String toJsonString() {
+ if (value instanceof String) {
+ return "\"" + escape(value.toString()) + "\"";
+ }
+ return value != null ? value.toString() : null;
+ }
+
+ @Override
+ public int hashCode() {
+ if (value instanceof String) {
+ return ((String) value).hashCode();
+ } else if (value instanceof Long) {
+ return ((Long) value).hashCode();
+ } else if (value instanceof Double) {
+ return ((Double) value).hashCode();
+ } else if (value instanceof Boolean) {
+ return ((Boolean) value).hashCode();
+ } else {
+ return super.hashCode();
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof JSONPrimitive)) {
+ return false;
+ }
+
+ JSONPrimitive o = (JSONPrimitive) obj;
+
+ if (value == null && o.getValue() == null) {
+ return true;
+ }
+
+ if (value != null && o.getValue() != null) {
+ if (value.getClass().equals(o.getValue().getClass())) {
+ return value.equals(o.getValue());
+ }
+ }
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/JSONParser.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,300 @@
+/* Generated By:JavaCC: Do not edit this line. JSONParser.java */
+package jdk.internal.management.remote.rest.json.parser;
+
+import java.io.StringReader;
+import jdk.internal.management.remote.rest.json.*;
+
+public class JSONParser implements JSONParserConstants {
+
+ public JSONParser(String input) {
+ this(new StringReader(input));
+ }
+
+ public JSONElement parse() throws ParseException {
+ return jsonValue();
+ }
+
+ final public JSONElement jsonValue() throws ParseException {
+ JSONElement x;
+ switch (jj_nt.kind) {
+ case 16:
+ x = object();
+ break;
+ case 20:
+ x = list();
+ break;
+ case QUOTED_STRING:
+ x = string();
+ break;
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ x = number();
+ break;
+ case BOOL_LITERAL:
+ x = boolVal();
+ break;
+ case NULL:
+ x = nullVal();
+ break;
+ default:
+ jj_la1[0] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ {if (true) return x;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONObject object() throws ParseException {
+ final JSONObject jobject = new JSONObject();
+ JSONPrimitive key;
+ JSONElement value;
+ jj_consume_token(16);
+ key = string();
+ jj_consume_token(17);
+ value = jsonValue();
+ jobject.put((String)key.getValue(), value);
+ label_1:
+ while (true) {
+ switch (jj_nt.kind) {
+ case 18:
+ ;
+ break;
+ default:
+ jj_la1[1] = jj_gen;
+ break label_1;
+ }
+ jj_consume_token(18);
+ key = string();
+ jj_consume_token(17);
+ value = jsonValue();
+ jobject.put((String)key.getValue(), value);
+ }
+ jj_consume_token(19);
+ {if (true) return jobject;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONArray list() throws ParseException {
+ final JSONArray jarray = new JSONArray();
+ JSONElement value;
+ jj_consume_token(20);
+ value = jsonValue();
+ jarray.add(value);
+ label_2:
+ while (true) {
+ switch (jj_nt.kind) {
+ case 18:
+ ;
+ break;
+ default:
+ jj_la1[2] = jj_gen;
+ break label_2;
+ }
+ jj_consume_token(18);
+ value = jsonValue();
+ jarray.add(value);
+ }
+ jj_consume_token(21);
+ {if (true) return jarray;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONPrimitive nullVal() throws ParseException {
+ jj_consume_token(NULL);
+ {if (true) return null;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONPrimitive boolVal() throws ParseException {
+ jj_consume_token(BOOL_LITERAL);
+ {if (true) return new JSONPrimitive(Boolean.parseBoolean(token.image));}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONPrimitive number() throws ParseException {
+ Token t;
+ switch (jj_nt.kind) {
+ case INTEGER_LITERAL:
+ t = jj_consume_token(INTEGER_LITERAL);
+ {if (true) return new JSONPrimitive(Long.parseLong(t.image));}
+ break;
+ case FLOATING_POINT_LITERAL:
+ t = jj_consume_token(FLOATING_POINT_LITERAL);
+ {if (true) return new JSONPrimitive(Double.parseDouble(t.image));}
+ break;
+ default:
+ jj_la1[3] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+ final public JSONPrimitive string() throws ParseException {
+ Token t;
+ t = jj_consume_token(QUOTED_STRING);
+ {if (true) return new JSONPrimitive(t.image.substring(1,t.image.length()-1));}
+ throw new Error("Missing return statement in function");
+ }
+
+ /** Generated Token Manager. */
+ public JSONParserTokenManager token_source;
+ JavaCharStream jj_input_stream;
+ /** Current token. */
+ public Token token;
+ /** Next token. */
+ public Token jj_nt;
+ private int jj_gen;
+ final private int[] jj_la1 = new int[4];
+ static private int[] jj_la1_0;
+ static {
+ jj_la1_init_0();
+ }
+ private static void jj_la1_init_0() {
+ jj_la1_0 = new int[] {0x11e180,0x40000,0x40000,0x180,};
+ }
+
+ /** Constructor with InputStream. */
+ public JSONParser(java.io.InputStream stream) {
+ this(stream, null);
+ }
+ /** Constructor with InputStream and supplied encoding */
+ public JSONParser(java.io.InputStream stream, String encoding) {
+ try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+ token_source = new JSONParserTokenManager(jj_input_stream);
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ /** Reinitialise. */
+ public void ReInit(java.io.InputStream stream) {
+ ReInit(stream, null);
+ }
+ /** Reinitialise. */
+ public void ReInit(java.io.InputStream stream, String encoding) {
+ try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+ token_source.ReInit(jj_input_stream);
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ /** Constructor. */
+ public JSONParser(java.io.Reader stream) {
+ jj_input_stream = new JavaCharStream(stream, 1, 1);
+ token_source = new JSONParserTokenManager(jj_input_stream);
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ /** Reinitialise. */
+ public void ReInit(java.io.Reader stream) {
+ jj_input_stream.ReInit(stream, 1, 1);
+ token_source.ReInit(jj_input_stream);
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ /** Constructor with generated Token Manager. */
+ public JSONParser(JSONParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ /** Reinitialise. */
+ public void ReInit(JSONParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ token.next = jj_nt = token_source.getNextToken();
+ jj_gen = 0;
+ for (int i = 0; i < 4; i++) jj_la1[i] = -1;
+ }
+
+ private Token jj_consume_token(int kind) throws ParseException {
+ Token oldToken = token;
+ if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
+ else jj_nt = jj_nt.next = token_source.getNextToken();
+ if (token.kind == kind) {
+ jj_gen++;
+ return token;
+ }
+ jj_nt = token;
+ token = oldToken;
+ jj_kind = kind;
+ throw generateParseException();
+ }
+
+
+/** Get the next Token. */
+ final public Token getNextToken() {
+ if ((token = jj_nt).next != null) jj_nt = jj_nt.next;
+ else jj_nt = jj_nt.next = token_source.getNextToken();
+ jj_gen++;
+ return token;
+ }
+
+/** Get the specific Token. */
+ final public Token getToken(int index) {
+ Token t = token;
+ for (int i = 0; i < index; i++) {
+ if (t.next != null) t = t.next;
+ else t = t.next = token_source.getNextToken();
+ }
+ return t;
+ }
+
+ private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+ private int[] jj_expentry;
+ private int jj_kind = -1;
+
+ /** Generate ParseException. */
+ public ParseException generateParseException() {
+ jj_expentries.clear();
+ boolean[] la1tokens = new boolean[22];
+ if (jj_kind >= 0) {
+ la1tokens[jj_kind] = true;
+ jj_kind = -1;
+ }
+ for (int i = 0; i < 4; i++) {
+ if (jj_la1[i] == jj_gen) {
+ for (int j = 0; j < 32; j++) {
+ if ((jj_la1_0[i] & (1<<j)) != 0) {
+ la1tokens[j] = true;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < 22; i++) {
+ if (la1tokens[i]) {
+ jj_expentry = new int[1];
+ jj_expentry[0] = i;
+ jj_expentries.add(jj_expentry);
+ }
+ }
+ int[][] exptokseq = new int[jj_expentries.size()][];
+ for (int i = 0; i < jj_expentries.size(); i++) {
+ exptokseq[i] = jj_expentries.get(i);
+ }
+ return new ParseException(token, exptokseq, tokenImage);
+ }
+
+ /** Enable tracing. */
+ final public void enable_tracing() {
+ }
+
+ /** Disable tracing. */
+ final public void disable_tracing() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/JSONParserConstants.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,61 @@
+/* Generated By:JavaCC: Do not edit this line. JSONParserConstants.java */
+package jdk.internal.management.remote.rest.json.parser;
+
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+public interface JSONParserConstants {
+
+ /** End of File. */
+ int EOF = 0;
+ /** RegularExpression Id. */
+ int INTEGER_LITERAL = 7;
+ /** RegularExpression Id. */
+ int FLOATING_POINT_LITERAL = 8;
+ /** RegularExpression Id. */
+ int FRAC = 9;
+ /** RegularExpression Id. */
+ int EXPONENT = 10;
+ /** RegularExpression Id. */
+ int DIGITS = 11;
+ /** RegularExpression Id. */
+ int DIGIT = 12;
+ /** RegularExpression Id. */
+ int QUOTED_STRING = 13;
+ /** RegularExpression Id. */
+ int BOOL_LITERAL = 14;
+ /** RegularExpression Id. */
+ int NULL = 15;
+
+ /** Lexical state. */
+ int DEFAULT = 0;
+
+ /** Literal token values. */
+ String[] tokenImage = {
+ "<EOF>",
+ "\" \"",
+ "\"\\b\"",
+ "\"\\t\"",
+ "\"\\n\"",
+ "\"\\r\"",
+ "\"\\f\"",
+ "<INTEGER_LITERAL>",
+ "<FLOATING_POINT_LITERAL>",
+ "<FRAC>",
+ "<EXPONENT>",
+ "<DIGITS>",
+ "<DIGIT>",
+ "<QUOTED_STRING>",
+ "<BOOL_LITERAL>",
+ "\"null\"",
+ "\"{\"",
+ "\":\"",
+ "\",\"",
+ "\"}\"",
+ "\"[\"",
+ "\"]\"",
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/JSONParserTokenManager.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,540 @@
+/* Generated By:JavaCC: Do not edit this line. JSONParserTokenManager.java */
+package jdk.internal.management.remote.rest.json.parser;
+import java.io.StringReader;
+import jdk.internal.management.remote.rest.json.*;
+
+/** Token Manager. */
+public class JSONParserTokenManager implements JSONParserConstants
+{
+
+ /** Debug output. */
+ public java.io.PrintStream debugStream = System.out;
+ /** Set debug output. */
+ public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0)
+{
+ switch (pos)
+ {
+ default :
+ return -1;
+ }
+}
+private final int jjStartNfa_0(int pos, long active0)
+{
+ return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_0()
+{
+ switch(curChar)
+ {
+ case 44:
+ return jjStopAtPos(0, 18);
+ case 58:
+ return jjStopAtPos(0, 17);
+ case 91:
+ return jjStopAtPos(0, 20);
+ case 93:
+ return jjStopAtPos(0, 21);
+ case 78:
+ case 110:
+ return jjMoveStringLiteralDfa1_0(0x8000L);
+ case 123:
+ return jjStopAtPos(0, 16);
+ case 125:
+ return jjStopAtPos(0, 19);
+ default :
+ return jjMoveNfa_0(0, 0);
+ }
+}
+private int jjMoveStringLiteralDfa1_0(long active0)
+{
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(0, active0);
+ return 1;
+ }
+ switch(curChar)
+ {
+ case 85:
+ case 117:
+ return jjMoveStringLiteralDfa2_0(active0, 0x8000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(0, active0);
+}
+private int jjMoveStringLiteralDfa2_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(0, old0);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(1, active0);
+ return 2;
+ }
+ switch(curChar)
+ {
+ case 76:
+ case 108:
+ return jjMoveStringLiteralDfa3_0(active0, 0x8000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(1, active0);
+}
+private int jjMoveStringLiteralDfa3_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(1, old0);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(2, active0);
+ return 3;
+ }
+ switch(curChar)
+ {
+ case 76:
+ case 108:
+ if ((active0 & 0x8000L) != 0L)
+ return jjStopAtPos(3, 15);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(2, active0);
+}
+static final long[] jjbitVec0 = {
+ 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+ 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private int jjMoveNfa_0(int startState, int curPos)
+{
+ int startsAt = 0;
+ jjnewStateCnt = 29;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int kind = 0x7fffffff;
+ for (;;)
+ {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ long l = 1L << curChar;
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 0:
+ if ((0x3ff000000000000L & l) != 0L)
+ {
+ if (kind > 7)
+ kind = 7;
+ jjCheckNAddStates(0, 6);
+ }
+ else if (curChar == 45)
+ jjCheckNAddStates(7, 10);
+ else if (curChar == 34)
+ jjCheckNAddStates(11, 13);
+ break;
+ case 1:
+ if ((0xfffffffbffffffffL & l) != 0L)
+ jjCheckNAddStates(11, 13);
+ break;
+ case 3:
+ if (curChar == 34)
+ jjCheckNAddStates(11, 13);
+ break;
+ case 4:
+ if (curChar == 34 && kind > 13)
+ kind = 13;
+ break;
+ case 13:
+ if (curChar == 45)
+ jjCheckNAddStates(7, 10);
+ break;
+ case 14:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 7)
+ kind = 7;
+ jjCheckNAdd(14);
+ break;
+ case 15:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(15, 16);
+ break;
+ case 16:
+ if (curChar == 46)
+ jjCheckNAdd(17);
+ break;
+ case 17:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 8)
+ kind = 8;
+ jjCheckNAdd(17);
+ break;
+ case 18:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(18, 19);
+ break;
+ case 20:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(21);
+ break;
+ case 21:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 8)
+ kind = 8;
+ jjCheckNAdd(21);
+ break;
+ case 22:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(22, 23);
+ break;
+ case 23:
+ if (curChar == 46)
+ jjCheckNAdd(24);
+ break;
+ case 24:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(24, 25);
+ break;
+ case 26:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(27);
+ break;
+ case 27:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 8)
+ kind = 8;
+ jjCheckNAdd(27);
+ break;
+ case 28:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 7)
+ kind = 7;
+ jjCheckNAddStates(0, 6);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ long l = 1L << (curChar & 077);
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 0:
+ if ((0x4000000040L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 11;
+ else if ((0x10000000100000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 7;
+ break;
+ case 1:
+ if ((0xffffffffefffffffL & l) != 0L)
+ jjCheckNAddStates(11, 13);
+ break;
+ case 2:
+ if (curChar == 92)
+ jjstateSet[jjnewStateCnt++] = 3;
+ break;
+ case 3:
+ if ((0x14404410144044L & l) != 0L)
+ jjCheckNAddStates(11, 13);
+ break;
+ case 5:
+ if ((0x2000000020L & l) != 0L && kind > 14)
+ kind = 14;
+ break;
+ case 6:
+ if ((0x20000000200000L & l) != 0L)
+ jjCheckNAdd(5);
+ break;
+ case 7:
+ if ((0x4000000040000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 6;
+ break;
+ case 8:
+ if ((0x10000000100000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 7;
+ break;
+ case 9:
+ if ((0x8000000080000L & l) != 0L)
+ jjCheckNAdd(5);
+ break;
+ case 10:
+ if ((0x100000001000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 9;
+ break;
+ case 11:
+ if ((0x200000002L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 10;
+ break;
+ case 12:
+ if ((0x4000000040L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 11;
+ break;
+ case 19:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(14, 15);
+ break;
+ case 25:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(16, 17);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else
+ {
+ int hiByte = (curChar >> 8);
+ int i1 = hiByte >> 6;
+ long l1 = 1L << (hiByte & 077);
+ int i2 = (curChar & 0xff) >> 6;
+ long l2 = 1L << (curChar & 077);
+ do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 1:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjAddStates(11, 13);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ if (kind != 0x7fffffff)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt) == (startsAt = 29 - (jjnewStateCnt = startsAt)))
+ return curPos;
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) { return curPos; }
+ }
+}
+static final int[] jjnextStates = {
+ 14, 15, 16, 18, 19, 22, 23, 14, 15, 18, 22, 1, 2, 4, 20, 21,
+ 26, 27,
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+ switch(hiByte)
+ {
+ case 0:
+ return ((jjbitVec2[i2] & l2) != 0L);
+ default :
+ if ((jjbitVec0[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+}
+
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, null,
+null, null, null, "\173", "\72", "\54", "\175", "\133", "\135", };
+
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+ "DEFAULT",
+};
+static final long[] jjtoToken = {
+ 0x3fe181L,
+};
+static final long[] jjtoSkip = {
+ 0x7eL,
+};
+protected JavaCharStream input_stream;
+private final int[] jjrounds = new int[29];
+private final int[] jjstateSet = new int[58];
+protected char curChar;
+/** Constructor. */
+public JSONParserTokenManager(JavaCharStream stream){
+ if (JavaCharStream.staticFlag)
+ throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+ input_stream = stream;
+}
+
+/** Constructor. */
+public JSONParserTokenManager(JavaCharStream stream, int lexState){
+ this(stream);
+ SwitchTo(lexState);
+}
+
+/** Reinitialise parser. */
+public void ReInit(JavaCharStream stream)
+{
+ jjmatchedPos = jjnewStateCnt = 0;
+ curLexState = defaultLexState;
+ input_stream = stream;
+ ReInitRounds();
+}
+private void ReInitRounds()
+{
+ int i;
+ jjround = 0x80000001;
+ for (i = 29; i-- > 0;)
+ jjrounds[i] = 0x80000000;
+}
+
+/** Reinitialise parser. */
+public void ReInit(JavaCharStream stream, int lexState)
+{
+ ReInit(stream);
+ SwitchTo(lexState);
+}
+
+/** Switch to specified lex state. */
+public void SwitchTo(int lexState)
+{
+ if (lexState >= 1 || lexState < 0)
+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+ else
+ curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+ final Token t;
+ final String curTokenImage;
+ final int beginLine;
+ final int endLine;
+ final int beginColumn;
+ final int endColumn;
+ String im = jjstrLiteralImages[jjmatchedKind];
+ curTokenImage = (im == null) ? input_stream.GetImage() : im;
+ beginLine = input_stream.getBeginLine();
+ beginColumn = input_stream.getBeginColumn();
+ endLine = input_stream.getEndLine();
+ endColumn = input_stream.getEndColumn();
+ t = Token.newToken(jjmatchedKind, curTokenImage);
+
+ t.beginLine = beginLine;
+ t.endLine = endLine;
+ t.beginColumn = beginColumn;
+ t.endColumn = endColumn;
+
+ return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+public Token getNextToken()
+{
+ Token matchedToken;
+ int curPos = 0;
+
+ EOFLoop :
+ for (;;)
+ {
+ try
+ {
+ curChar = input_stream.BeginToken();
+ }
+ catch(java.io.IOException e)
+ {
+ jjmatchedKind = 0;
+ matchedToken = jjFillToken();
+ return matchedToken;
+ }
+
+ try { input_stream.backup(0);
+ while (curChar <= 32 && (0x100003700L & (1L << curChar)) != 0L)
+ curChar = input_stream.BeginToken();
+ }
+ catch (java.io.IOException e1) { continue EOFLoop; }
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = jjMoveStringLiteralDfa0_0();
+ if (jjmatchedKind != 0x7fffffff)
+ {
+ if (jjmatchedPos + 1 < curPos)
+ input_stream.backup(curPos - jjmatchedPos - 1);
+ if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+ {
+ matchedToken = jjFillToken();
+ return matchedToken;
+ }
+ else
+ {
+ continue EOFLoop;
+ }
+ }
+ int error_line = input_stream.getEndLine();
+ int error_column = input_stream.getEndColumn();
+ String error_after = null;
+ boolean EOFSeen = false;
+ try { input_stream.readChar(); input_stream.backup(1); }
+ catch (java.io.IOException e1) {
+ EOFSeen = true;
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ if (curChar == '\n' || curChar == '\r') {
+ error_line++;
+ error_column = 0;
+ }
+ else
+ error_column++;
+ }
+ if (!EOFSeen) {
+ input_stream.backup(1);
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ }
+ throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+ }
+}
+
+private void jjCheckNAdd(int state)
+{
+ if (jjrounds[state] != jjround)
+ {
+ jjstateSet[jjnewStateCnt++] = state;
+ jjrounds[state] = jjround;
+ }
+}
+private void jjAddStates(int start, int end)
+{
+ do {
+ jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+ } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+ jjCheckNAdd(state1);
+ jjCheckNAdd(state2);
+}
+
+private void jjCheckNAddStates(int start, int end)
+{
+ do {
+ jjCheckNAdd(jjnextStates[start]);
+ } while (start++ != end);
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/JavaCharStream.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,617 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package jdk.internal.management.remote.rest.json.parser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (with java-like unicode escape processing).
+ */
+
+public
+class JavaCharStream
+{
+ /** Whether parser is static. */
+ public static final boolean staticFlag = false;
+
+ static final int hexval(char c) throws java.io.IOException {
+ switch(c)
+ {
+ case '0' :
+ return 0;
+ case '1' :
+ return 1;
+ case '2' :
+ return 2;
+ case '3' :
+ return 3;
+ case '4' :
+ return 4;
+ case '5' :
+ return 5;
+ case '6' :
+ return 6;
+ case '7' :
+ return 7;
+ case '8' :
+ return 8;
+ case '9' :
+ return 9;
+
+ case 'a' :
+ case 'A' :
+ return 10;
+ case 'b' :
+ case 'B' :
+ return 11;
+ case 'c' :
+ case 'C' :
+ return 12;
+ case 'd' :
+ case 'D' :
+ return 13;
+ case 'e' :
+ case 'E' :
+ return 14;
+ case 'f' :
+ case 'F' :
+ return 15;
+ }
+
+ throw new java.io.IOException(); // Should never come here
+ }
+
+/** Position in buffer. */
+ public int bufpos = -1;
+ int bufsize;
+ int available;
+ int tokenBegin;
+ protected int bufline[];
+ protected int bufcolumn[];
+
+ protected int column = 0;
+ protected int line = 1;
+
+ protected boolean prevCharIsCR = false;
+ protected boolean prevCharIsLF = false;
+
+ protected java.io.Reader inputStream;
+
+ protected char[] nextCharBuf;
+ protected char[] buffer;
+ protected int maxNextCharInd = 0;
+ protected int nextCharInd = -1;
+ protected int inBuf = 0;
+ protected int tabSize = 8;
+
+ protected void setTabSize(int i) { tabSize = i; }
+ protected int getTabSize(int i) { return tabSize; }
+
+ protected void ExpandBuff(boolean wrapAround)
+ {
+ char[] newbuffer = new char[bufsize + 2048];
+ int newbufline[] = new int[bufsize + 2048];
+ int newbufcolumn[] = new int[bufsize + 2048];
+
+ try
+ {
+ if (wrapAround)
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufcolumn = newbufcolumn;
+
+ bufpos += (bufsize - tokenBegin);
+ }
+ else
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ bufcolumn = newbufcolumn;
+
+ bufpos -= tokenBegin;
+ }
+ }
+ catch (Throwable t)
+ {
+ throw new Error(t.getMessage());
+ }
+
+ available = (bufsize += 2048);
+ tokenBegin = 0;
+ }
+
+ protected void FillBuff() throws java.io.IOException
+ {
+ int i;
+ if (maxNextCharInd == 4096)
+ maxNextCharInd = nextCharInd = 0;
+
+ try {
+ if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+ 4096 - maxNextCharInd)) == -1)
+ {
+ inputStream.close();
+ throw new java.io.IOException();
+ }
+ else
+ maxNextCharInd += i;
+ return;
+ }
+ catch(java.io.IOException e) {
+ if (bufpos != 0)
+ {
+ --bufpos;
+ backup(0);
+ }
+ else
+ {
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+ throw e;
+ }
+ }
+
+ protected char ReadByte() throws java.io.IOException
+ {
+ if (++nextCharInd >= maxNextCharInd)
+ FillBuff();
+
+ return nextCharBuf[nextCharInd];
+ }
+
+/** @return starting character for token. */
+ public char BeginToken() throws java.io.IOException
+ {
+ if (inBuf > 0)
+ {
+ --inBuf;
+
+ if (++bufpos == bufsize)
+ bufpos = 0;
+
+ tokenBegin = bufpos;
+ return buffer[bufpos];
+ }
+
+ tokenBegin = 0;
+ bufpos = -1;
+
+ return readChar();
+ }
+
+ protected void AdjustBuffSize()
+ {
+ if (available == bufsize)
+ {
+ if (tokenBegin > 2048)
+ {
+ bufpos = 0;
+ available = tokenBegin;
+ }
+ else
+ ExpandBuff(false);
+ }
+ else if (available > tokenBegin)
+ available = bufsize;
+ else if ((tokenBegin - available) < 2048)
+ ExpandBuff(true);
+ else
+ available = tokenBegin;
+ }
+
+ protected void UpdateLineColumn(char c)
+ {
+ column++;
+
+ if (prevCharIsLF)
+ {
+ prevCharIsLF = false;
+ line += (column = 1);
+ }
+ else if (prevCharIsCR)
+ {
+ prevCharIsCR = false;
+ if (c == '\n')
+ {
+ prevCharIsLF = true;
+ }
+ else
+ line += (column = 1);
+ }
+
+ switch (c)
+ {
+ case '\r' :
+ prevCharIsCR = true;
+ break;
+ case '\n' :
+ prevCharIsLF = true;
+ break;
+ case '\t' :
+ column--;
+ column += (tabSize - (column % tabSize));
+ break;
+ default :
+ break;
+ }
+
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+
+/** Read a character. */
+ public char readChar() throws java.io.IOException
+ {
+ if (inBuf > 0)
+ {
+ --inBuf;
+
+ if (++bufpos == bufsize)
+ bufpos = 0;
+
+ return buffer[bufpos];
+ }
+
+ char c;
+
+ if (++bufpos == available)
+ AdjustBuffSize();
+
+ if ((buffer[bufpos] = c = ReadByte()) == '\\')
+ {
+ UpdateLineColumn(c);
+
+ int backSlashCnt = 1;
+
+ for (;;) // Read all the backslashes
+ {
+ if (++bufpos == available)
+ AdjustBuffSize();
+
+ try
+ {
+ if ((buffer[bufpos] = c = ReadByte()) != '\\')
+ {
+ UpdateLineColumn(c);
+ // found a non-backslash char.
+ if ((c == 'u') && ((backSlashCnt & 1) == 1))
+ {
+ if (--bufpos < 0)
+ bufpos = bufsize - 1;
+
+ break;
+ }
+
+ backup(backSlashCnt);
+ return '\\';
+ }
+ }
+ catch(java.io.IOException e)
+ {
+ // We are returning one backslash so we should only backup (count-1)
+ if (backSlashCnt > 1)
+ backup(backSlashCnt-1);
+
+ return '\\';
+ }
+
+ UpdateLineColumn(c);
+ backSlashCnt++;
+ }
+
+ // Here, we have seen an odd number of backslash's followed by a 'u'
+ try
+ {
+ while ((c = ReadByte()) == 'u')
+ ++column;
+
+ buffer[bufpos] = c = (char)(hexval(c) << 12 |
+ hexval(ReadByte()) << 8 |
+ hexval(ReadByte()) << 4 |
+ hexval(ReadByte()));
+
+ column += 4;
+ }
+ catch(java.io.IOException e)
+ {
+ throw new Error("Invalid escape character at line " + line +
+ " column " + column + ".");
+ }
+
+ if (backSlashCnt == 1)
+ return c;
+ else
+ {
+ backup(backSlashCnt - 1);
+ return '\\';
+ }
+ }
+ else
+ {
+ UpdateLineColumn(c);
+ return c;
+ }
+ }
+
+ @Deprecated
+ /**
+ * @deprecated
+ * @see #getEndColumn
+ */
+ public int getColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ @Deprecated
+ /**
+ * @deprecated
+ * @see #getEndLine
+ */
+ public int getLine() {
+ return bufline[bufpos];
+ }
+
+/** Get end column. */
+ public int getEndColumn() {
+ return bufcolumn[bufpos];
+ }
+
+/** Get end line. */
+ public int getEndLine() {
+ return bufline[bufpos];
+ }
+
+/** @return column of token start */
+ public int getBeginColumn() {
+ return bufcolumn[tokenBegin];
+ }
+
+/** @return line number of token start */
+ public int getBeginLine() {
+ return bufline[tokenBegin];
+ }
+
+/** Retreat. */
+ public void backup(int amount) {
+
+ inBuf += amount;
+ if ((bufpos -= amount) < 0)
+ bufpos += bufsize;
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.Reader dstream,
+ int startline, int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ nextCharBuf = new char[4096];
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.Reader dstream,
+ int startline, int startcolumn)
+ {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.Reader dstream)
+ {
+ this(dstream, 1, 1, 4096);
+ }
+/** Reinitialise. */
+ public void ReInit(java.io.Reader dstream,
+ int startline, int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ if (buffer == null || buffersize != buffer.length)
+ {
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ nextCharBuf = new char[4096];
+ }
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ nextCharInd = bufpos = -1;
+ }
+
+/** Reinitialise. */
+ public void ReInit(java.io.Reader dstream,
+ int startline, int startcolumn)
+ {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+/** Reinitialise. */
+ public void ReInit(java.io.Reader dstream)
+ {
+ ReInit(dstream, 1, 1, 4096);
+ }
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+ {
+ this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn) throws java.io.UnsupportedEncodingException
+ {
+ this(dstream, encoding, startline, startcolumn, 4096);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn)
+ {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+ {
+ this(dstream, encoding, 1, 1, 4096);
+ }
+
+/** Constructor. */
+ public JavaCharStream(java.io.InputStream dstream)
+ {
+ this(dstream, 1, 1, 4096);
+ }
+
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+ {
+ ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+ }
+
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize)
+ {
+ ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+ }
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn) throws java.io.UnsupportedEncodingException
+ {
+ ReInit(dstream, encoding, startline, startcolumn, 4096);
+ }
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn)
+ {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+ {
+ ReInit(dstream, encoding, 1, 1, 4096);
+ }
+
+/** Reinitialise. */
+ public void ReInit(java.io.InputStream dstream)
+ {
+ ReInit(dstream, 1, 1, 4096);
+ }
+
+ /** @return token image as String */
+ public String GetImage()
+ {
+ if (bufpos >= tokenBegin)
+ return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+ new String(buffer, 0, bufpos + 1);
+ }
+
+ /** @return suffix */
+ public char[] GetSuffix(int len)
+ {
+ char[] ret = new char[len];
+
+ if ((bufpos + 1) >= len)
+ System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+ else
+ {
+ System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+ len - bufpos - 1);
+ System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+ }
+
+ return ret;
+ }
+
+ /** Set buffers back to null when finished. */
+ public void Done()
+ {
+ nextCharBuf = null;
+ buffer = null;
+ bufline = null;
+ bufcolumn = null;
+ }
+
+ /**
+ * Method to adjust line and column numbers for the start of a token.
+ */
+ public void adjustBeginLineColumn(int newLine, int newCol)
+ {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin)
+ {
+ len = bufpos - tokenBegin + inBuf + 1;
+ }
+ else
+ {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+ {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ }
+
+ if (i < len)
+ {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len)
+ {
+ if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ }
+ }
+
+ line = bufline[j];
+ column = bufcolumn[j];
+ }
+
+}
+/* JavaCC - OriginalChecksum=de12e5c213925fe7f76171e55cffcda1 (do not edit this line) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/JsonParser.jj Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * This is the JavaCC grammar file for a JSON parser. The productions are
+ * based on syntax diagrams as specified at json.org
+ * Every type of JSON is represent by a JSONElement. JSON Objects are mapped to
+ * by LinkedHashMap via JSONObject. JSON Arrays are mapped to ArrayList via JSONArray
+ * String, Number, Boolean and null are wrapped into a JSONPrimitive.
+ * Control characters inside a string (JSONPrimitive(String)) are not escaped and are passed through
+ * to ouput JSON string generated by toJsonString method of JSONElement.
+ * Inside a String, only backslash ('\') and double quote ('"') characters
+ * are escaped by a backslash, if they are not already escaped.
+ * Applications consuming json string generated by JSON* objects must take care
+ * to escape control characters within strings by prefixing with a backslash character,
+ * if not already escaped.
+ */
+options {
+ STATIC=false;
+ ERROR_REPORTING=true;
+ JAVA_UNICODE_ESCAPE=true;
+ UNICODE_INPUT=true;
+ IGNORE_CASE=true;
+ CACHE_TOKENS=true;
+// DEBUG_PARSER=true;
+// DEBUG_LOOKAHEAD=true;
+// DEBUG_TOKEN_MANAGER=true;
+}
+
+PARSER_BEGIN(JSONParser)
+
+package jdk.internal.management.remote.rest.json.parser;
+
+import java.io.StringReader;
+import jdk.internal.management.remote.rest.json.*;
+
+public class JSONParser {
+
+ public JSONParser(String input) {
+ this(new StringReader(input));
+ }
+
+ public JSONElement parse() throws ParseException {
+ return jsonValue();
+ }
+}
+
+PARSER_END(JSONParser)
+
+SKIP: {
+ " " | "\b" | "\t" | "\n" | "\r" | "\f"
+}
+
+TOKEN:{
+ <INTEGER_LITERAL : (["-"])? (<DIGITS>)>
+| < FLOATING_POINT_LITERAL:
+ <INTEGER_LITERAL> <FRAC>
+| <INTEGER_LITERAL> <EXPONENT>
+| <INTEGER_LITERAL> <FRAC> <EXPONENT>
+ >
+| < #FRAC: "." <DIGITS>>
+| < #EXPONENT: ["e","E"] (["+","-"])? <DIGITS> >
+| < #DIGITS : (<DIGIT>)+>
+| < #DIGIT: ["0"-"9"]>
+| <QUOTED_STRING: "\"" ((~["\"","\\"]) | ("\\" ( ["n","t","b","r","f","\\","\""])))* "\"">
+| <BOOL_LITERAL : "true" | "false">
+| <NULL: "null">
+}
+
+JSONElement jsonValue() : {
+ JSONElement x;
+}{
+ ( x = object()
+ | x = list()
+ | x = string()
+ | x = number()
+ | x = boolVal()
+ | x = nullVal()
+ )
+ { return x; }
+}
+
+JSONObject object() : {
+ final JSONObject jobject = new JSONObject();
+ JSONPrimitive key;
+ JSONElement value;
+}{
+ "{"
+ (key = string())
+ ":"
+ value = jsonValue()
+ { jobject.put((String)key.getValue(), value);}
+ (
+ ","
+ (key = string())
+ ":"
+ value = jsonValue()
+ { jobject.put((String)key.getValue(), value);}
+ )*
+ "}"
+ { return jobject; }
+}
+
+JSONArray list() : {
+ final JSONArray jarray = new JSONArray();
+ JSONElement value;
+}{
+ "["
+ value = jsonValue()
+ { jarray.add(value);}
+ (
+ ","
+ value = jsonValue()
+ { jarray.add(value); }
+ )*
+ "]"
+
+ { return jarray; }
+}
+
+JSONPrimitive nullVal(): {} {
+ <NULL>
+ { return null; }
+}
+
+JSONPrimitive boolVal(): {}
+{
+ <BOOL_LITERAL>
+ {return new JSONPrimitive(Boolean.parseBoolean(token.image));}
+}
+
+JSONPrimitive number(): {
+ Token t;
+}{
+ (t = <INTEGER_LITERAL> { return new JSONPrimitive(Long.parseLong(t.image));})
+ | (t = <FLOATING_POINT_LITERAL> { return new JSONPrimitive(Double.parseDouble(t.image));})
+}
+
+JSONPrimitive string() : {
+ Token t;
+}{
+ (t = <QUOTED_STRING>)
+ { return new JSONPrimitive(t.image.substring(1,t.image.length()-1)); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/ParseException.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,187 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
+/* JavaCCOptions:KEEP_LINE_COL=null */
+package jdk.internal.management.remote.rest.json.parser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+ /**
+ * The version identifier for this Serializable class.
+ * Increment only if the <i>serialized</i> form of the
+ * class changes.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * This constructor is used by the method "generateParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set.
+ */
+ public ParseException(Token currentTokenVal,
+ int[][] expectedTokenSequencesVal,
+ String[] tokenImageVal
+ )
+ {
+ super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
+ currentToken = currentTokenVal;
+ expectedTokenSequences = expectedTokenSequencesVal;
+ tokenImage = tokenImageVal;
+ }
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+
+ public ParseException() {
+ super();
+ }
+
+ /** Constructor with message. */
+ public ParseException(String message) {
+ super(message);
+ }
+
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ public Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ public int[][] expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants interface.
+ */
+ public String[] tokenImage;
+
+ /**
+ * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser) the correct error message
+ * gets displayed.
+ */
+ private static String initialise(Token currentToken,
+ int[][] expectedTokenSequences,
+ String[] tokenImage) {
+ String eol = System.getProperty("line.separator", "\n");
+ StringBuffer expected = new StringBuffer();
+ int maxSize = 0;
+ for (int i = 0; i < expectedTokenSequences.length; i++) {
+ if (maxSize < expectedTokenSequences[i].length) {
+ maxSize = expectedTokenSequences[i].length;
+ }
+ for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+ expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+ }
+ if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+ expected.append("...");
+ }
+ expected.append(eol).append(" ");
+ }
+ String retval = "Encountered \"";
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0) retval += " ";
+ if (tok.kind == 0) {
+ retval += tokenImage[0];
+ break;
+ }
+ retval += " " + tokenImage[tok.kind];
+ retval += " \"";
+ retval += add_escapes(tok.image);
+ retval += " \"";
+ tok = tok.next;
+ }
+ retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+ retval += "." + eol;
+ if (expectedTokenSequences.length == 1) {
+ retval += "Was expecting:" + eol + " ";
+ } else {
+ retval += "Was expecting one of:" + eol + " ";
+ }
+ retval += expected.toString();
+ return retval;
+ }
+
+ /**
+ * The end of line string for this machine.
+ */
+ protected String eol = System.getProperty("line.separator", "\n");
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ static String add_escapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+}
+/* JavaCC - OriginalChecksum=676ade0685adcc4f6efc95fc903deb31 (do not edit this line) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/Token.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,131 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package jdk.internal.management.remote.rest.json.parser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+ /**
+ * The version identifier for this Serializable class.
+ * Increment only if the <i>serialized</i> form of the
+ * class changes.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * An integer that describes the kind of this token. This numbering
+ * system is determined by JavaCCParser, and a table of these numbers is
+ * stored in the file ...Constants.java.
+ */
+ public int kind;
+
+ /** The line number of the first character of this Token. */
+ public int beginLine;
+ /** The column number of the first character of this Token. */
+ public int beginColumn;
+ /** The line number of the last character of this Token. */
+ public int endLine;
+ /** The column number of the last character of this Token. */
+ public int endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ public String image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to null. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ public Token next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to null.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToken field is null).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is null.
+ */
+ public Token specialToken;
+
+ /**
+ * An optional attribute value of the Token.
+ * Tokens which are not used as syntactic sugar will often contain
+ * meaningful values that will be used later on by the compiler or
+ * interpreter. This attribute value is often different from the image.
+ * Any subclass of Token that actually wants to return a non-null value can
+ * override this method as appropriate.
+ */
+ public Object getValue() {
+ return null;
+ }
+
+ /**
+ * No-argument constructor
+ */
+ public Token() {}
+
+ /**
+ * Constructs a new token for the specified Image.
+ */
+ public Token(int kind)
+ {
+ this(kind, null);
+ }
+
+ /**
+ * Constructs a new token for the specified Image and Kind.
+ */
+ public Token(int kind, String image)
+ {
+ this.kind = kind;
+ this.image = image;
+ }
+
+ /**
+ * Returns the image.
+ */
+ public String toString()
+ {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simply add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken(ofKind, image);
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use sit in your lexical actions.
+ */
+ public static Token newToken(int ofKind, String image)
+ {
+ switch(ofKind)
+ {
+ default : return new Token(ofKind, image);
+ }
+ }
+
+ public static Token newToken(int ofKind)
+ {
+ return newToken(ofKind, null);
+ }
+
+}
+/* JavaCC - OriginalChecksum=4fed70c581b710c02d269444889ad1b8 (do not edit this line) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/json/parser/TokenMgrError.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,147 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+package jdk.internal.management.remote.rest.json.parser;
+
+/** Token Manager Error. */
+public class TokenMgrError extends Error
+{
+
+ /**
+ * The version identifier for this Serializable class.
+ * Increment only if the <i>serialized</i> form of the
+ * class changes.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /**
+ * Lexical error occurred.
+ */
+ static final int LEXICAL_ERROR = 0;
+
+ /**
+ * An attempt was made to create a second instance of a static token manager.
+ */
+ static final int STATIC_LEXER_ERROR = 1;
+
+ /**
+ * Tried to change to an invalid lexical state.
+ */
+ static final int INVALID_LEXICAL_STATE = 2;
+
+ /**
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ static final int LOOP_DETECTED = 3;
+
+ /**
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /**
+ * Replaces unprintable characters by their escaped (or unicode escaped)
+ * equivalents in the given string
+ */
+ protected static final String addEscapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexical error
+ * curLexState : lexical state in which this error occurred
+ * errorLine : line number when the error occurred
+ * errorColumn : column number when the error occurred
+ * errorAfter : prefix that was seen before this error occurred
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+ return("Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+ "after : \"" + addEscapes(errorAfter) + "\"");
+ }
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ public String getMessage() {
+ return super.getMessage();
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ /** No arg constructor. */
+ public TokenMgrError() {
+ }
+
+ /** Constructor with message and reason. */
+ public TokenMgrError(String message, int reason) {
+ super(message);
+ errorCode = reason;
+ }
+
+ /** Full Constructor. */
+ public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+ }
+}
+/* JavaCC - OriginalChecksum=98060294001500754a7ee499f6ef09d6 (do not edit this line) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/mapper/JSONDataException.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.mapper;
+
+/**
+ * @author harsha
+ */
+public class JSONDataException extends Exception {
+
+ private static final long serialVersionUID = 2430707794210680967L;
+
+ public JSONDataException() {
+ super();
+ }
+
+ public JSONDataException(String s) {
+ super(s);
+ }
+
+ public JSONDataException(String s, Throwable ex) {
+ super(s, ex);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/mapper/JSONMapper.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.mapper;
+
+import jdk.internal.management.remote.rest.json.JSONElement;
+
+/**
+ * @author harsha
+ */
+public interface JSONMapper {
+ public Object toJavaObject(JSONElement jsonValue) throws JSONDataException;
+
+ public JSONElement toJsonValue(Object data) throws JSONMappingException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/mapper/JSONMappingException.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.mapper;
+
+/**
+ * @author harsha
+ */
+public class JSONMappingException extends Exception {
+
+ private static final long serialVersionUID = -3099452281524742227L;
+
+ public static final JSONMappingException UNABLE_TO_MAP = new JSONMappingException("Unable to map types");
+
+ public JSONMappingException() {
+ super();
+ }
+
+ public JSONMappingException(String s) {
+ super(s);
+ }
+
+ public JSONMappingException(String s, Throwable ex) {
+ super(s, ex);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/jdk/internal/management/remote/rest/mapper/JSONMappingFactory.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.management.remote.rest.mapper;
+
+import jdk.internal.management.remote.rest.json.JSONArray;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.JSONObject;
+import jdk.internal.management.remote.rest.json.JSONPrimitive;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.openmbean.*;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author harsha
+ */
+public final class JSONMappingFactory {
+
+ public static final JSONMappingFactory INSTANCE;
+ private static final Map<Class<?>, JSONMapper> typeMapper;
+ private static final Map<String, Class<?>> primitiveMap = new HashMap<>();
+
+ static {
+ // Make order of Initialization explicit
+ typeMapper = new HashMap<>();
+
+ primitiveMap.put("boolean", Boolean.TYPE);
+ primitiveMap.put("int", Integer.TYPE);
+ primitiveMap.put("long", Long.TYPE);
+ primitiveMap.put("double", Double.TYPE);
+ primitiveMap.put("float", Float.TYPE);
+ primitiveMap.put("bool", Boolean.TYPE);
+ primitiveMap.put("char", Character.TYPE);
+ primitiveMap.put("byte", Byte.TYPE);
+ primitiveMap.put("void", Void.TYPE);
+ primitiveMap.put("short", Short.TYPE);
+
+ INSTANCE = new JSONMappingFactory();
+ }
+
+ private JSONMappingFactory() {
+
+ typeMapper.put(void.class, new VoidMapper());
+ typeMapper.put(Void.class, new VoidMapper());
+
+ typeMapper.put(boolean.class, new BooleanMapper());
+ typeMapper.put(Boolean.class, new BooleanMapper());
+
+ typeMapper.put(byte.class, new ByteMapper());
+ typeMapper.put(Byte.class, new ByteMapper());
+
+ typeMapper.put(short.class, new ShortMapper());
+ typeMapper.put(Short.class, new ShortMapper());
+
+ typeMapper.put(int.class, new IntegerMapper());
+ typeMapper.put(Integer.class, new IntegerMapper());
+
+ typeMapper.put(long.class, new LongMapper());
+ typeMapper.put(Long.class, new LongMapper());
+
+ typeMapper.put(float.class, new FloatMapper());
+ typeMapper.put(Float.class, new FloatMapper());
+
+ typeMapper.put(double.class, new DoubleMapper());
+ typeMapper.put(Double.class, new DoubleMapper());
+
+ typeMapper.put(char.class, new CharacterMapper());
+ typeMapper.put(Character.class, new CharacterMapper());
+
+ typeMapper.put(String.class, new StringMapper());
+ typeMapper.put(BigInteger.class, new BigIntegerMapper());
+ typeMapper.put(BigDecimal.class, new BigDecimalMapper());
+ typeMapper.put(ObjectName.class, new ObjectNameMapper());
+ typeMapper.put(Date.class, new DateMapper());
+ }
+
+ private Class<?> getArrayComponent(Class<?> cls) {
+ if (cls == null) {
+ return cls;
+ }
+ Class<?> compType = cls;
+ // TODO: Add check for max array dimention of 15
+ while (compType.isArray()) {
+ compType = compType.getComponentType();
+ }
+ return compType;
+ }
+
+ private Object getArrayElement(Object arrayObj) {
+ if (arrayObj != null && arrayObj.getClass().isArray()) {
+ while (arrayObj.getClass().isArray()) {
+ Class<?> componentType = arrayObj.getClass().getComponentType();
+ if (Array.getLength(arrayObj) > 0) {
+ Object component = null;
+ for (int i = 0; i < Array.getLength(arrayObj); i++) {
+ component = Array.get(arrayObj, i);
+ if (component != null) {
+ break;
+ }
+ }
+ if (component == null) {
+ return null;
+ }
+ if (componentType.isPrimitive()) {
+ componentType = component.getClass();
+ }
+ arrayObj = componentType.cast(component);
+ } else {
+ return null;
+ }
+ }
+ }
+ return arrayObj;
+ }
+
+ // TODO: This should be access controlled. Define new permissions
+ public void addMapping(Class<?> cls, JSONMapper mapper) {
+ Class<?> input = cls;
+ if (cls.isArray()) {
+ input = getArrayComponent(cls);
+ }
+ if (!typeMapper.containsKey(input)) {
+ typeMapper.put(input, mapper);
+ }
+ }
+
+ public JSONMapper getTypeMapper(Object object) {
+ return getTypeMapper(object, true);
+ }
+
+ private JSONMapper getTypeMapper(Object object, boolean deepTypeCheck) {
+ if (object == null) return null;
+ Class<?> cls = object.getClass();
+ if (cls.isArray()) {
+ Object arrayElement = getArrayElement(object);
+ if (arrayElement instanceof CompositeData) {
+ CompositeData cds = (CompositeData) arrayElement;
+ return new OpenArrayTypeMapper(cls, cds.getCompositeType());
+ } else if (arrayElement instanceof TabularData) {
+ TabularData tds = (TabularData) arrayElement;
+ return new OpenArrayTypeMapper(cls, tds.getTabularType());
+ }
+ }
+
+ if (object instanceof CompositeData) {
+ CompositeData cd = (CompositeData) object;
+ return getTypeMapper(cd.getCompositeType());
+ } else if (object instanceof TabularData) {
+ TabularData cds = (TabularData) object;
+ return getTypeMapper(cds.getTabularType());
+ } else if (object instanceof Collection<?>) {
+ if (deepTypeCheck) {
+ Collection<?> c = (Collection<?>) object;
+ boolean unknownMapper = c.stream().anyMatch(k -> (k != null) && (getTypeMapper(k) == null));
+ if (unknownMapper)
+ return null;
+ }
+ return new CollectionMapper();
+ } else if (object instanceof Map<?, ?>) {
+ if (deepTypeCheck) {
+ Map<?, ?> map = (Map<?, ?>) object;
+ boolean unknownMapper = map.keySet().stream().
+ anyMatch(k -> ((k != null) && (getTypeMapper(k) == null)
+ || (map.get(k) != null && getTypeMapper(map.get(k)) == null)));
+ if (unknownMapper)
+ return null;
+ }
+ return new MapMapper();
+ } else {
+ return getTypeMapper(cls);
+ }
+ }
+
+ public JSONMapper getTypeMapper(Class<?> type) {
+ if (type == null) return null;
+ if (type.isArray()) {
+ Class<?> compType = getArrayComponent(type);
+ if (typeMapper.get(compType) != null) {
+ return new GenericArrayMapper(type);
+ } else {
+ return null;
+ }
+ }
+ return typeMapper.get(type);
+ }
+
+ public JSONMapper getTypeMapper(OpenType<?> type) {
+ if (type instanceof CompositeType) {
+ return new OpenCompositeTypeMapper((CompositeType) type);
+ } else if (type instanceof SimpleType) {
+ try {
+ return getTypeMapper(Class.forName((type).getClassName()));
+ } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
+ throw new RuntimeException(ex);
+ }
+ } else if (type instanceof ArrayType) {
+ try {
+ ArrayType<?> at = (ArrayType) type;
+ Class<?> arrayClass = Class.forName(type.getClassName());
+ return new OpenArrayTypeMapper(arrayClass, at.getElementOpenType());
+ } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
+ throw new RuntimeException(ex);
+ }
+ } else if (type instanceof TabularType) {
+ return new OpenTabularTypeMapper((TabularType) type);
+ }
+ return null; //keep compiler happy
+ }
+
+ public boolean isTypeMapped(String type) throws ClassNotFoundException {
+ if (primitiveMap.get(type) != null) {
+ return true;
+ }
+ Class<?> inputCls = Class.forName(type);
+ inputCls = getArrayComponent(inputCls);
+ if (inputCls.equals(CompositeData.class) || inputCls.equals(TabularData.class)
+ || inputCls.equals(CompositeDataSupport.class) || inputCls.equals(TabularDataSupport.class)) {
+ return true;
+ }
+ return JSONMappingFactory.INSTANCE.getTypeMapper(inputCls) != null;
+ }
+
+ private static class OpenArrayTypeMapper extends GenericArrayMapper {
+
+ OpenArrayTypeMapper(Class<?> type, OpenType<?> elementOpenType) {
+ super(type);
+ mapper = JSONMappingFactory.INSTANCE.getTypeMapper(elementOpenType);
+ }
+ }
+
+ // This mapper array type for any java class
+ private static class GenericArrayMapper implements JSONMapper {
+
+ private final Class<?> type;
+ protected JSONMapper mapper;
+
+ GenericArrayMapper(Class<?> type) {
+ this.type = type;
+ mapper = JSONMappingFactory.INSTANCE.getTypeMapper(JSONMappingFactory.INSTANCE.getArrayComponent(type));
+ }
+
+ private Object handleArrayType(Class<?> classType, JSONElement jsonValue) throws JSONDataException {
+ if (!(jsonValue instanceof JSONArray)) {
+ throw new JSONDataException("Invald JSON data format");
+ }
+ JSONArray jarr = (JSONArray) jsonValue;
+ Class<?> compType = classType.getComponentType();
+ Object resultArray = Array.newInstance(compType, jarr.size());
+
+ for (int i = 0; i < jarr.size(); i++) {
+ if (compType != null && compType.isArray()) {
+ Array.set(resultArray, i, handleArrayType(compType, jarr.get(i)));
+ } else {
+ Array.set(resultArray, i, mapper.toJavaObject(jarr.get(i)));
+ }
+ }
+ return resultArray;
+ }
+
+ @Override
+ public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ return handleArrayType(type, jsonValue);
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ if (data == null) {
+ return null;
+ }
+ if (!data.getClass().equals(type)) {
+ throw new JSONMappingException("Illegal type : " + data.getClass());
+ }
+ return getJasonValue(data);
+ }
+
+ private JSONElement getJasonValue(Object data) throws JSONMappingException {
+ if (data == null) {
+ return null;
+ }
+ if (!data.getClass().isArray()) {
+ return mapper.toJsonValue(data);
+ } else {
+ JSONArray jArray = new JSONArray();
+ for (int i = 0; i < Array.getLength(data); i++) {
+ jArray.add(getJasonValue(Array.get(data, i)));
+ }
+ return jArray;
+ }
+ }
+ }
+
+ /*
+ Mapper for compositeType. CompositeData cannot be mapped without it's associated
+ OpenType
+ */
+ private static class OpenCompositeTypeMapper implements JSONMapper {
+
+ private final CompositeType type;
+
+ OpenCompositeTypeMapper(CompositeType type) {
+ this.type = type;
+ }
+
+ @Override
+ public CompositeDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (!(jsonValue instanceof JSONObject)) {
+ throw new JSONDataException("JSON String not an object");
+ }
+
+ JSONObject jObject = (JSONObject) jsonValue;
+ Map<String, Object> compositeDataMap = new HashMap<>();
+ for (String itemName : type.keySet()) {
+ OpenType<?> oType = type.getType(itemName);
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
+ compositeDataMap.put(itemName, typeMapper.toJavaObject(jObject.get(itemName)));
+ }
+ try {
+ return new CompositeDataSupport(type, compositeDataMap);
+ } catch (OpenDataException ex) {
+ throw new JSONDataException("Could not create CompositeData", ex);
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object d) throws JSONMappingException {
+ CompositeData data = (CompositeData) d;
+ if (data == null) {
+ return null;
+ }
+ JSONObject jObject = new JSONObject();
+ for (String itemName : type.keySet()) {
+ OpenType<?> oType = type.getType(itemName);
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
+ if (typeMapper != null) {
+ jObject.put(itemName, typeMapper.toJsonValue(data.get(itemName)));
+ } else {
+ System.out.println("Unable to find mapper for : " + oType);
+ }
+ }
+ return jObject;
+ }
+ }
+
+ private static class OpenTabularTypeMapper implements JSONMapper {
+
+ private final TabularType type;
+
+ public OpenTabularTypeMapper(TabularType type) {
+ this.type = type;
+ }
+
+ /*
+ Tabular data in JSON can follow below schema
+ {
+ "keys" : [<list of elements>],
+ "rows": [{ <CompositeData> }]
+ }
+ */
+ @Override
+ public TabularDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ if (data == null) {
+ return null;
+ }
+ TabularDataSupport tds = (TabularDataSupport) data;
+ JSONArray jsonArray = new JSONArray();
+ for (Map.Entry<Object, Object> a : tds.entrySet()) {
+ CompositeData cds = (CompositeData) a.getValue();
+ JSONMapper cdsMapper = JSONMappingFactory.INSTANCE.getTypeMapper(cds);
+ if (cdsMapper != null) {
+ jsonArray.add(cdsMapper.toJsonValue(cds));
+ }
+ }
+ return jsonArray;
+ }
+ }
+
+ private static class VoidMapper implements JSONMapper {
+ @Override
+ public Void toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ return null;
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return null;
+ }
+ }
+
+ private static class BooleanMapper implements JSONMapper {
+
+ @Override
+ public Boolean toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Boolean) {
+ return (Boolean) ((JSONPrimitive) jsonValue).getValue();
+ } else {
+ throw new JSONDataException("Invalid type conversion - cannot convert "
+ + ((JSONPrimitive) jsonValue).getValue()
+ + "(" + ((JSONPrimitive) jsonValue).getValue().getClass() + ")" + " to boolean");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Boolean) data);
+ }
+ }
+
+ private static class ByteMapper implements JSONMapper {
+
+ @Override
+ public Byte toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return ((Long) ((JSONPrimitive) jsonValue).getValue()).byteValue();
+ } else {
+ throw new JSONDataException("Invalid type convertion - cannot convert "
+ + (((JSONPrimitive) jsonValue).getValue().getClass()) + " to byte");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Byte) data);
+ }
+ }
+
+ private static class ShortMapper implements JSONMapper {
+
+ @Override
+ public Short toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return ((Long) ((JSONPrimitive) jsonValue).getValue()).shortValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Short) data);
+ }
+ }
+
+ private static class IntegerMapper implements JSONMapper {
+
+ @Override
+ public Integer toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return ((Long) ((JSONPrimitive) jsonValue).getValue()).intValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Integer) data);
+ }
+ }
+
+ private static class LongMapper implements JSONMapper {
+
+ @Override
+ public Long toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return (Long) ((JSONPrimitive) jsonValue).getValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Long) data);
+ }
+ }
+
+ private static class FloatMapper implements JSONMapper {
+
+ @Override
+ public Float toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
+ return ((Double) ((JSONPrimitive) jsonValue).getValue()).floatValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Float) data);
+ }
+ }
+
+ private static class DoubleMapper implements JSONMapper {
+
+ @Override
+ public Double toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return (Double) ((JSONPrimitive) jsonValue).getValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Double) data);
+ }
+ }
+
+ private static class CharacterMapper implements JSONMapper {
+
+ @Override
+ public Character toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
+ String data = ((String) ((JSONPrimitive) jsonValue).getValue());
+ if (data.length() < 1) {
+ throw new JSONDataException("Invalid char");
+ }
+ return data.charAt(0);
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((Character) data);
+ }
+ }
+
+ private static class StringMapper implements JSONMapper {
+
+ @Override
+ public String toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
+ return (String) ((JSONPrimitive) jsonValue).getValue();
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive((String) data);
+ }
+ }
+
+ private static class BigDecimalMapper implements JSONMapper {
+
+ @Override
+ public BigDecimal toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
+ return BigDecimal.valueOf((Double) ((JSONPrimitive) jsonValue).getValue());
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive(((BigDecimal) data).doubleValue());
+ }
+ }
+
+ private static class BigIntegerMapper implements JSONMapper {
+
+ @Override
+ public BigInteger toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
+ return BigInteger.valueOf((Long) ((JSONPrimitive) jsonValue).getValue());
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive(((BigInteger) data).longValue());
+ }
+ }
+
+ private static class ObjectNameMapper implements JSONMapper {
+
+ @Override
+ public ObjectName toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
+ try {
+ return new ObjectName((String) ((JSONPrimitive) jsonValue).getValue());
+ } catch (MalformedObjectNameException ex) {
+ throw new JSONDataException("Invalid Objectname");
+ }
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive(data.toString());
+ }
+ }
+
+ private static class DateMapper implements JSONMapper {
+
+ private final DateFormat df = new SimpleDateFormat("YYYY-MM-DD");
+
+ @Override
+ public Date toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
+ String data = ((String) ((JSONPrimitive) jsonValue).getValue());
+ try {
+ return df.parse(data);
+ } catch (ParseException ex) {
+ throw new JSONDataException("Invalid Data " + data);
+ }
+ } else {
+ throw new JSONDataException("Invalid JSON");
+ }
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ return new JSONPrimitive(df.format((Date) data));
+ }
+ }
+
+ private static final class MapMapper implements JSONMapper {
+
+ @Override
+ public Map<String, Object> toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONObject) {
+ JSONObject obj = (JSONObject) jsonValue;
+ Map<String, Object> result = new HashMap<>(obj.size());
+ for (String k : result.keySet()) {
+ JSONElement elem = obj.get(k);
+ if (elem instanceof JSONPrimitive) {
+ result.put(k, ((JSONPrimitive) elem).getValue());
+ } else {
+ JSONMapper mapper;
+ if (elem instanceof JSONObject) {
+ mapper = new MapMapper();
+ result.put(k, mapper.toJavaObject(elem));
+ } else if (elem instanceof JSONArray) {
+ mapper = new CollectionMapper();
+ result.put(k, mapper.toJavaObject(elem));
+ } else {
+ throw new JSONDataException("Unable to map : " + elem.getClass());
+ }
+ }
+ }
+ return result;
+ }
+ throw new JSONDataException("Inalid input");
+ }
+
+ @Override
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ if (data instanceof Map) {
+ JSONObject jobj = new JSONObject();
+ Map<?, ?> input = (Map<?, ?>) data;
+ for (Object k : input.keySet()) {
+ String key = k.toString();
+ final Object value = input.get(k);
+ if (value == null) {
+ jobj.put(key, (JSONElement) null);
+ } else {
+ JSONMapper mapper = JSONMappingFactory.INSTANCE
+ .getTypeMapper(value,false); // Disable repeated type checking
+ if (mapper == null) {
+ throw new JSONMappingException("Unable to map : " + value);
+ }
+ jobj.put(key, mapper.toJsonValue(value));
+ }
+ }
+ return jobj;
+ } else {
+ throw new JSONMappingException("Invalid Input");
+ }
+ }
+ }
+
+ private static final class CollectionMapper implements JSONMapper {
+
+ public CollectionMapper() {
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
+ if (jsonValue instanceof JSONArray) {
+ JSONArray jarr = (JSONArray) jsonValue;
+ List<Object> result = new ArrayList<>(jarr.size());
+ for (JSONElement elem : jarr) {
+ if (elem instanceof JSONPrimitive) {
+ result.add(((JSONPrimitive) elem).getValue());
+ } else {
+ JSONMapper mapper;
+ if (elem instanceof JSONObject) {
+ mapper = new MapMapper();
+ result.add(mapper.toJavaObject(elem));
+ } else if (elem instanceof JSONArray) {
+ mapper = new CollectionMapper();
+ result.add(mapper.toJavaObject(elem));
+ } else {
+ throw new JSONDataException("Unable to map : " + elem.getClass());
+ }
+ }
+ }
+ return result;
+ }
+ throw new JSONDataException("Inalid input");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public JSONElement toJsonValue(Object data) throws JSONMappingException {
+ if (data instanceof Collection) {
+ JSONArray jarr = new JSONArray();
+ Collection<?> c = (Collection<?>) data;
+ for (Object next : c) {
+ JSONMapper typeMapper = JSONMappingFactory.INSTANCE.
+ getTypeMapper(next, false); // Disable repeated type checking for collection
+ if (typeMapper == null) {
+ throw JSONMappingException.UNABLE_TO_MAP;
+ }
+ jarr.add(typeMapper.toJsonValue(next));
+ }
+ return jarr;
+ } else {
+ throw new JSONMappingException("Invalid Input");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.management.rest/share/classes/module-info.java Fri Jan 19 13:46:27 2018 +0530
@@ -0,0 +1,11 @@
+import jdk.internal.management.remote.rest.RestAdapterProvider;
+
+module jdk.management.rest {
+
+ requires transitive java.management;
+ requires jdk.httpserver;
+ requires jdk.management.agent;
+
+ provides jdk.internal.agent.spi.AgentProvider with
+ RestAdapterProvider;
+}
--- a/test/jdk/javax/management/remote/rest/JsonParserSpecialCharTest.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/JsonParserSpecialCharTest.java Fri Jan 19 13:46:27 2018 +0530
@@ -1,16 +1,16 @@
/* @test
* @summary JSON parser test for special characters in json string
- * @modules java.management.rest/com.oracle.jmx.remote.rest.json
- * java.management.rest/com.oracle.jmx.remote.rest.json.parser
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest.json
+ * jdk.management.rest/jdk.internal.management.remote.rest.json.parser
* @build JsonParserSpecialCharTest
* @run testng/othervm JsonParserSpecialCharTest
*/
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
-import com.oracle.jmx.remote.rest.json.parser.TokenMgrError;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.parser.JSONParser;
+import jdk.internal.management.remote.rest.json.parser.ParseException;
+import jdk.internal.management.remote.rest.json.parser.TokenMgrError;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
--- a/test/jdk/javax/management/remote/rest/JsonParserTest.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/JsonParserTest.java Fri Jan 19 13:46:27 2018 +0530
@@ -1,29 +1,31 @@
/* @test
* @summary Test JSON parser for a random json node tree
- * @modules java.management.rest/com.oracle.jmx.remote.rest.json
- * java.management.rest/com.oracle.jmx.remote.rest.json.parser
+ * @library /test/lib
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest.json
+ * jdk.management.rest/jdk.internal.management.remote.rest.json.parser
* @build JsonParserTest
* @run main JsonParserTest
*/
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.json.parser.ParseException;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.parser.JSONParser;
+import jdk.internal.management.remote.rest.json.parser.ParseException;
import java.util.*;
/**
- * Below class tests JSON parser for a randomly generated JSON string.
- * The Json string is generated by converting a randomly generated tree into a string
- * Each node in the tree is either a json Object, array or a primitive.
+ * Thisclass tests the JSON parser for a randomly generated JSON string.
+ * Json strings are generated by walking a randomly generated tree of JSON Nodes.
+ * Each node in the tree is either a json Object, an array or a primitive.
* Primitive node generates string, number, boolean or null as a string.
- * Json Number is generated according to the syntax graph as in json.org
- * Json string is generated along with all the control characters, and by escaping
- * only backslash and double quote characters.
+ * Json Number is generated according to the syntax graph as specified in json.org
+ * Json string is generated inclusive of all the control characters.
+ * Only backslash and double quote characters are escaped via backslash.
*/
public class JsonParserTest {
- static final Random RANDOM = new Random(System.currentTimeMillis());
+ static final Random RANDOM = jdk.test.lib.Utils.getRandomInstance();
static int maxChildrenPerNode;
public static void main(String[] args) throws ParseException {
@@ -40,7 +42,7 @@
}
String str = node.toJsonString();
JSONParser parser = new JSONParser(str);
- com.oracle.jmx.remote.rest.json.JSONElement parse = parser.parse();
+ JSONElement parse = parser.parse();
parse.toJsonString();
System.out.println("Finished iteration : " + i + ", Node count :" + totalNodes);
}
--- a/test/jdk/javax/management/remote/rest/RestAdapterConfigTest.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/RestAdapterConfigTest.java Fri Jan 19 13:46:27 2018 +0530
@@ -2,7 +2,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import javax.management.remote.rest.PlatformRestAdapter;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@@ -20,10 +20,11 @@
/* @test
* @summary Configuration test for rest adapter
* @library /test/lib
- * @modules java.management.rest/com.oracle.jmx.remote.rest.http
- * java.management.rest/com.oracle.jmx.remote.rest.json
- * java.management.rest/com.oracle.jmx.remote.rest.json.parser
- * java.management.rest/com.oracle.jmx.remote.rest.mapper
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest.http
+ * jdk.management.rest/jdk.internal.management.remote.rest.json
+ * jdk.management.rest/jdk.internal.management.remote.rest.json.parser
+ * jdk.management.rest/jdk.internal.management.remote.rest.mapper
+ * jdk.management.rest/jdk.internal.management.remote.rest
* @build RestAdapterConfigTest RestAdapterTest
* @run testng/othervm RestAdapterConfigTest
*/
--- a/test/jdk/javax/management/remote/rest/RestAdapterPerformanceTest.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/RestAdapterPerformanceTest.java Fri Jan 19 13:46:27 2018 +0530
@@ -1,23 +1,31 @@
import org.testng.annotations.Test;
-
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import java.util.Set;
import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import jdk.test.lib.Utils;
+
+/* @test
+ * @summary Performance test for rest adapter
+ * @library /test/lib
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest.http
+ * jdk.management.rest/jdk.internal.management.remote.rest.json
+ * jdk.management.rest/jdk.internal.management.remote.rest.json.parser
+ * jdk.management.rest/jdk.internal.management.remote.rest.mapper
+ * jdk.management.rest/jdk.internal.management.remote.rest
+ * @build RestAdapterPerformanceTest RestAdapterTest
+ * @run testng/othervm RestAdapterPerformanceTest
+ */
@Test
public class RestAdapterPerformanceTest {
- private static Random random = new Random(System.currentTimeMillis());
+ private static Random random = Utils.getRandomInstance();
private static AtomicInteger count = new AtomicInteger(1);
@Test
--- a/test/jdk/javax/management/remote/rest/RestAdapterTest.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/RestAdapterTest.java Fri Jan 19 13:46:27 2018 +0530
@@ -1,12 +1,12 @@
-import com.oracle.jmx.remote.rest.http.HttpResponse;
-import com.oracle.jmx.remote.rest.http.HttpUtil;
-import com.oracle.jmx.remote.rest.json.JSONArray;
-import com.oracle.jmx.remote.rest.json.JSONElement;
-import com.oracle.jmx.remote.rest.json.JSONObject;
-import com.oracle.jmx.remote.rest.json.JSONPrimitive;
-import com.oracle.jmx.remote.rest.json.parser.JSONParser;
-import com.oracle.jmx.remote.rest.mapper.JSONMapper;
-import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory;
+import jdk.internal.management.remote.rest.http.HttpResponse;
+import jdk.internal.management.remote.rest.http.HttpUtil;
+import jdk.internal.management.remote.rest.json.JSONArray;
+import jdk.internal.management.remote.rest.json.JSONElement;
+import jdk.internal.management.remote.rest.json.JSONObject;
+import jdk.internal.management.remote.rest.json.JSONPrimitive;
+import jdk.internal.management.remote.rest.json.parser.JSONParser;
+import jdk.internal.management.remote.rest.mapper.JSONMapper;
+import jdk.internal.management.remote.rest.mapper.JSONMappingFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -15,7 +15,7 @@
import javax.management.*;
import javax.management.remote.*;
-import javax.management.remote.rest.PlatformRestAdapter;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
@@ -27,10 +27,11 @@
/* @test
* @summary Unit tests for Rest adapter
* @library /test/lib
- * @modules java.management.rest/com.oracle.jmx.remote.rest.http
- * java.management.rest/com.oracle.jmx.remote.rest.json
- * java.management.rest/com.oracle.jmx.remote.rest.json.parser
- * java.management.rest/com.oracle.jmx.remote.rest.mapper
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest.http
+ * jdk.management.rest/jdk.internal.management.remote.rest.json
+ * jdk.management.rest/jdk.internal.management.remote.rest.json.parser
+ * jdk.management.rest/jdk.internal.management.remote.rest.mapper
+ * jdk.management.rest/jdk.internal.management.remote.rest
* @build RestAdapterTest
* @run testng/othervm RestAdapterTest
*/
@@ -76,7 +77,7 @@
MBeanServerConnection mBeanServer = connector.getMBeanServerConnection();
Set<ObjectInstance> objectInstances = mBeanServer.queryMBeans(null, null);
return objectInstances.stream().map(a -> a.getObjectName().getCanonicalName()).collect(Collectors.toSet());
- } catch (Exception ex) {
+ } catch (IOException ex) {
throw new RuntimeException(ex);
}
}
--- a/test/jdk/javax/management/remote/rest/RunRestAdapter.java Fri Jan 05 13:42:53 2018 +0530
+++ b/test/jdk/javax/management/remote/rest/RunRestAdapter.java Fri Jan 19 13:46:27 2018 +0530
@@ -5,13 +5,12 @@
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
-import javax.management.remote.rest.PlatformRestAdapter;
+import jdk.internal.management.remote.rest.PlatformRestAdapter;
/**
* @test
- * @modules java.logging
- * java.management.rest
+ * @modules jdk.management.rest/jdk.internal.management.remote.rest
* @run main RunRestAdapter
*/
public class RunRestAdapter {