org.glassfish.admin.rest.provider.ProviderUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
* Portions Copyright [2017-2021] Payara Foundation and/or affiliates
*/
package org.glassfish.admin.rest.provider;
import com.sun.appserv.server.util.Version;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import jakarta.json.JsonArray;
import jakarta.json.JsonException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import org.glassfish.admin.rest.Constants;
import org.glassfish.admin.rest.utils.ResourceUtil;
import org.glassfish.admin.rest.utils.Util;
import org.glassfish.admin.rest.results.OptionsResult;
import org.glassfish.external.statistics.Statistic;
import org.glassfish.external.statistics.impl.StatisticImpl;
import org.jvnet.hk2.config.ConfigBean;
/**
*
* @author Pajeshwar Patil
* @author Ludovic Champenois [email protected]
*/
public class ProviderUtil {
public static final String KEY_CHILD_RESOURCE = "childResource";
public static final String KEY_CHILD_RESOURCES = "childResources";
public static final String KEY_COMMAND = "command";
public static final String KEY_COMMANDS = "commands";
public static final String KEY_ENTITY = "entity";
public static final String KEY_METHODS = "methods";
/**
* Produce a string in double quotes with backslash sequences in all the
* right places.
*/
public static String quote(String string) {
if (string == null || string.length() == 0) {
return "\"\"";
}
char b;
char c = 0;
int i;
int len = string.length();
StringBuilder sb = new StringBuilder(len + 4);
String t;
sb.append('"');
for (i = 0; i < len; i += 1) {
b = c;
c = string.charAt(i);
switch (c) {
case '\\':
case '"':
sb.append('\\');
sb.append(c);
break;
case '/':
if (b == '<') {
sb.append('\\');
}
sb.append(c);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (c < ' ') {
t = "000" + Integer.toHexString(c);
sb.append("\\u").append(t.substring(t.length() - 4));
} else {
sb.append(c);
}
}
}
sb.append('"');
return sb.toString();
}
protected static String slashToDash(String string) {
if (string != null && !string.isEmpty()) {
return string.replaceAll("/", "-");
} else {
return string;
}
}
protected static String readAsString(InputStream in) throws IOException {
Reader reader = new InputStreamReader(in);
StringBuilder sb = new StringBuilder();
char[] c = new char[1024];
int l;
while ((l = reader.read(c)) != -1) {
sb.append(c, 0, l);
}
return sb.toString();
}
public static String getElementLink(UriInfo uriInfo, String elementName) {
return uriInfo.getRequestUriBuilder().segment(elementName).build().toASCIIString();
}
protected static String getStartXmlElement(String name) {
assert((name != null) && name.length() > 0);
String result ="<";
result = result + name;
result = result + ">";
return result;
}
protected static String getEndXmlElement(String name) {
assert((name != null) && name.length() > 0);
String result ="<";
result = result + "/";
result = result + name;
result = result + ">";
return result;
}
public static Map getStatistics(Statistic statistic) throws
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
HashMap results = new HashMap();
Class classObject = statistic.getClass();
Method[] methods = classObject.getMethods();
for (Method method: methods) {
int modifier = method.getModifiers();
//consider only the public methods
if (Modifier.isPublic(modifier)) {
String name = method.getName();
//considier only the get* methods
if (name.startsWith("get")) {
name = name.substring("get".length());
Class> returnType = method.getReturnType();
//consider only the methods that return primitives or String objects)
if (returnType.isPrimitive() || "java.lang.String".equals(returnType.getName())) {
results.put(name, method.invoke(statistic));
} else {
//control should never reach here
//we do not expect statistic object to return object
//as value for any of it's stats.
}
}
}
}
return results;
}
public static Map getStatistic(Statistic statistic) {
Map statsMap;
// Most likely we will get the proxy of the StatisticImpl,
// reconvert that so you can access getStatisticAsMap method
if (Proxy.isProxyClass(statistic.getClass())) {
statsMap = ((StatisticImpl)Proxy.getInvocationHandler(statistic)).getStaticAsMap();
} else {
statsMap = ((StatisticImpl)statistic).getStaticAsMap();
}
return statsMap;
}
/**
* Converts a map of <String, Object> to a map of <String, String>
* @param map The map to convert
* @return the resulting map
*/
public static HashMap getStringMap(Map map) {
HashMap stringMap = new HashMap();
if (map != null) {
//Convert attribute value to String if that's not the case.
//Attribute value can be Boolean, Interger etc.
//We know keys in the map are always stored as String objects
for (Map.Entry entry : map.entrySet()) {
stringMap.put(entry.getKey(), entry.getValue().toString());
}
}
return stringMap;
}
protected static String getHtmlRepresentationForAttributes(ConfigBean proxy, UriInfo uriInfo) {
StringBuilder result = new StringBuilder();
MethodMetaData methodMetaData = ResourceUtil.getMethodMetaData(proxy.model);
Set parameters = methodMetaData.parameters();
Iterator iterator = parameters.iterator();
ParameterMetaData parameterMetaData;
String parameter;
while (iterator.hasNext()) {
parameter = iterator.next();
parameterMetaData = methodMetaData.getParameterMetaData(parameter);
//parameterMetaData contains attributeNames in camelCasedNames convert them to xmlNames to get the attribute's current value
String xmlAttributeName = ResourceUtil.convertToXMLName(parameter);
result.append(getHtmlRespresentationForParameter(parameter, parameterMetaData,
proxy.attribute(xmlAttributeName)));
}
if (result.length() > 0) {
return "";
} else {
return "";
}
}
protected static String getHtmlRespresentationsForCommand(MethodMetaData methodMetaData, String commandMethod,
String commandDisplayName, UriInfo uriInfo) {
StringBuilder result = new StringBuilder();
if (methodMetaData != null) {
Set parameters = methodMetaData.parameters();
Iterator iterator = parameters.iterator();
String parameter;
ParameterMetaData parameterMetaData;
while (iterator.hasNext()) {
parameter = iterator.next();
parameterMetaData = methodMetaData.getParameterMetaData(parameter);
if ((methodMetaData.isFileUploadOperation()) && (parameter.equals("id"))) {
parameterMetaData.setIsFileParameter(true);
}
result.append(getHtmlRespresentationForParameter(parameter, parameterMetaData));
}
//Fix to diplay component for commands with 0 arguments.
//For example, rotate-log or restart.
if (result.length() == 0) {
result.append(" ");
}
}
//hack-1 : support delete method for html
//hardcode "post" instead of commandMethod which should be post or delete.
String webMethod="post";
if (commandMethod.equalsIgnoreCase("get")){
webMethod="get";
}
if (result.length() != 0) {
//set encType if file upload operation
String encType = methodMetaData.isFileUploadOperation() ?
" enctype=\"multipart/form-data\"" : "" ;
result = new StringBuilder("");
}
return result.toString();
}
protected static String getHtmlForComponent(String component, String heading, String result) {
if ((component != null) && (component.length() > 0)) {
result = result + "" + heading + "
";
result = result + component;
result = result + "
";
}
return result;
}
/**
* Method to get the hint to display in case module monitoring levels are OFF
*
* @param uriInfo the uri context object of the input request
* @param mediaType the media type of the input request
* @return a hit to display when module monitoring levels are all OFF
*/
protected static String getHint(UriInfo uriInfo, String mediaType) {
String result = "";
java.net.URI baseUri = uriInfo.getBaseUri();
String monitoringLevelsConfigUrl = baseUri.getScheme() + "://" +
baseUri.getHost() + ":" + baseUri.getPort() +
"/management/domain/configs/config/server-config/monitoring-service/module-monitoring-levels";
String name = Util.localStrings.getLocalString(
"rest.monitoring.levels.hint.heading", "Hint");
String value = Util.localStrings.getLocalString("rest.monitoring.levels.hint.message",
"Module monitoring levels may be OFF. To set module monitoring levels please visit following url: {0}", monitoringLevelsConfigUrl);
if (mediaType.equals(MediaType.TEXT_HTML)) {
monitoringLevelsConfigUrl =
"
" +
monitoringLevelsConfigUrl + "";
value = Util.localStrings.getLocalString("rest.monitoring.levels.hint.message",
"Module monitoring levels may be OFF. To set module monitoring levels please visit following url: {0}", monitoringLevelsConfigUrl);
result = result + "" + name + "
";
result = result + value + "
";
result = "" + result + "" + "
";
return result;
}
if (mediaType.equals(MediaType.APPLICATION_JSON)) {
result = " " + quote(name) + ":" + jsonValue(value);
return result;
}
if (mediaType.equals(MediaType.APPLICATION_XML)) {
result = result + " " + name + "=" + quote(value);
return result;
}
return result;
}
public static String jsonValue(Object value) {
String result ="";
if (value.getClass().getName().equals("java.lang.String")) {
result = quote(value.toString());
} else {
result = value.toString();
}
return result;
}
public static String getHtmlHeader(String baseUri) {
String title = Version.getVersion() + " REST Interface";
String result = "" + title + " ";
result = result + getInternalStyleSheet(baseUri);
result = result + getAjaxJavascript(baseUri);
result = result + "";
result = result + "" + title + "
";
result = result + "
";
return result;
}
protected static JsonArray getJsonForMethodMetaData(OptionsResult metaData) throws JsonException {
OptionsResultJsonProvider provider = new OptionsResultJsonProvider();
return provider.getRespresenationForMethodMetaData(metaData);
}
protected static String getJsonForMethodMetaData(OptionsResult metaData, String indent) {
OptionsResultJsonProvider provider = new OptionsResultJsonProvider();
return provider.getRespresenationForMethodMetaData(metaData).toString();
}
protected static String getXmlForMethodMetaData(OptionsResult metaData, String indent) {
OptionsResultXmlProvider provider = new OptionsResultXmlProvider();
return provider.getRespresenationForMethodMetaData(metaData, indent);
}
private static String getHtmlRespresentationForParameter(String parameter, ParameterMetaData parameterMetaData) {
return getHtmlRespresentationForParameter(parameter, parameterMetaData, null);
}
private static String getHtmlRespresentationForParameter(String parameter,
ParameterMetaData parameterMetaData, String parameterValue) {
if ("true".equals(parameterMetaData.getAttributeValue(Constants.DEPRECATED))) {
return "";
}
//set appropriate type of input field. In can be of type file or text
//file type is used in case of deploy operation
String parameterType = parameterMetaData.isFileParameter() ? "file" : "text";
StringBuilder result = new StringBuilder();
result.append("");
boolean isBoolean = false;
if((parameterMetaData.getAttributeValue(Constants.TYPE).endsWith(Constants.JAVA_BOOLEAN_TYPE)) ||
(parameterMetaData.getAttributeValue(Constants.TYPE).equals(Constants.XSD_BOOLEAN_TYPE))) {
isBoolean = true;
}
boolean hasAcceptableValues = false;
String acceptableValues = parameterMetaData.getAttributeValue(Constants.ACCEPTABLE_VALUES);
if ((acceptableValues != null) && (acceptableValues.length() > 0)) {
hasAcceptableValues = true;
}
boolean hasValue = false;
if ((parameterValue == null) || (parameterValue.equals(""))) {
String defaultValue = parameterMetaData.getAttributeValue(Constants.DEFAULT_VALUE);
if ((defaultValue != null) && (defaultValue.length() > 0)) {
parameterValue = defaultValue;
}
}
if ((parameterValue != null) && (parameterValue.length() > 0)) {
hasValue = true;
}
boolean keyAttribute = Boolean.valueOf(parameterMetaData.getAttributeValue(Constants.KEY));
if (keyAttribute) {
if (hasValue) {
result.append("");
} else { //no value for the key, so we are in create mode, enable the entry field in the ui
//control should never reach here.
result.append("");
}
} else {
if (isBoolean || hasAcceptableValues) {
//use combo box
result.append("");
} else {
//use text box
String field;
boolean isList = parameterMetaData.getAttributeValue(Constants.TYPE).equals("interface java.util.List");
if (hasValue) {
field = "";
} else {
field = "";
}
result.append("").append(field);
if (isList) {
result.append("Add row");
}
result.append(" ");
}
}
return result.toString();
}
/**
* This method converts a string into string array, uses the delimeter as the
* separator character. If the delimiter is null, uses space as default.
*/
private static String[] stringToArray(String str, String delimiter) {
String[] retString = new String[0];
if (str != null) {
if(delimiter == null) {
delimiter = " ";
}
StringTokenizer tokens = new StringTokenizer(str, delimiter);
retString = new String[tokens.countTokens()];
int i = 0;
while(tokens.hasMoreTokens()) {
retString[i++] = tokens.nextToken();
}
}
return retString;
}
private static String getInternalStyleSheet(String baseUri) {
return " ";
}
private static String getAjaxJavascript(String baseUri) {
return " ";
}
}