All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bluenimble.platform.Lang Maven / Gradle / Ivy

There is a newer version: 2.50.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bluenimble.platform;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Pattern;

import com.bluenimble.platform.api.ApiResponse;
import com.bluenimble.platform.json.JsonArray;
import com.bluenimble.platform.json.JsonObject;
import com.bluenimble.platform.regex.WildcardCompiler;
import com.bluenimble.platform.regex.WildcardMatcher;
import com.bluenimble.platform.scripting.ScriptingEngineException;
import com.bluenimble.platform.templating.ExpressionCompiler;
import com.bluenimble.platform.templating.impls.BasicVariableResolver;
import com.bluenimble.platform.templating.impls.DefaultExpressionCompiler;

import jdk.nashorn.api.scripting.NashornException;

@SuppressWarnings("restriction")
public class Lang {
	
	public static final DefaultExpressionCompiler ExpressionCompiler 			 
															= new DefaultExpressionCompiler ().cacheSize (200);
	public static final DefaultExpressionCompiler ScriptedExpressionCompiler
															= new DefaultExpressionCompiler ().withScripting (true).cacheSize (200);
	
	public static final Null		Null 					= new Null ();
	
	private static final String 	ExpStart				= "{";
	private static final String 	ExpEnd					= "}";
	
	public static final String 		SNULL 					= "_X_";

	public static final String 		BLANK 					= "";
	public static final String 		SPACE 					= " ";
	public static final String 		PLUS 					= "+";
	public static final String 		STAR 					= "*";
	public static final String 		COLON 					= ":";
	public static final String 		SEMICOLON 				= ";";
	public static final String 		COMMA 					= ",";
	public static final String 		SLASH					= "/";
	public static final String 		BACKSLASH				= "\\";
	public static final String 		PIPE					= "|";
	public static final String 		DOT 					= ".";
	public static final String 		EQUALS 					= "=";
	public static final String 		DASH 					= "-";
	public static final String 		UNDERSCORE 				= "_";
	public static final String 		ENDLN 					= "\n";
	public static final String 		TAB 					= "\t";
	public static final String 		AMP 					= "&";
	public static final String 		QMARK 					= "?";
	public static final String 		XMARK					= "!";
	public static final String 		PERCENT					= "%";
	public static final String 		DOLLAR					= "$";
	public static final String 		SHARP					= "#";
	public static final String 		AT						= "@";
	public static final String 		LESS					= "<";
	public static final String 		GREATER					= ">";
	public static final String 		TILDE 					= "~";

	public static final String 		NULL 					= "null";
	public static final String 		URL_ACCESSOR 			= "://";

	public static final String 		DATA 					= "\"Data\"";

	public static final String 		OBJECT_OPEN				= "{";
	public static final String 		OBJECT_CLOSE			= "}";
	public static final String 		ARRAY_OPEN				= "[";
	public static final String 		ARRAY_CLOSE				= "]";
	public static final String 		PARENTH_OPEN			= "(";
	public static final String 		PARENTH_CLOSE			= ")";

	public static final String 		QUOTE					= "\"";
	public static final String 		APOS					= "'";
	public static final String 		QUESTION				= "?";
	
	public static final String 	 	FALSE 					= "false";
	public static final String 	 	TRUE 					= "true";

	public static final String 		EMTPY_OBJECT			= "{}";
	public static final String 		EMTPY_ARRAY				= "[]";
	public static final String 		EMTPY_DATA 				= "{\"items\": []}";

	public static final byte [] 	B_JSON_OBJECT_OPEN		= OBJECT_OPEN.getBytes ();
	public static final byte [] 	B_JSON_OBJECT_CLOSE		= OBJECT_CLOSE.getBytes ();
	public static final byte [] 	B_JSON_ARRAY_OPEN		= ARRAY_OPEN.getBytes ();
	public static final byte [] 	B_JSON_ARRAY_CLOSE		= ARRAY_CLOSE.getBytes ();

	public static final byte []		B_QUOT					= QUOTE.getBytes ();
	public static final byte [] 	B_COLON 				= COLON.getBytes ();
	public static final byte [] 	B_COMMA 				= COMMA.getBytes ();
	public static final byte [] 	B_JSON_DATA 			= DATA.getBytes ();

	public static final byte [] 	B_EMTPY_OBJECT			= EMTPY_OBJECT.getBytes ();
	public static final byte [] 	B_EMTPY_ARRAY			= EMTPY_ARRAY.getBytes ();
	public static final byte [] 	B_EMTPY_DATA 			= EMTPY_DATA.getBytes ();
	
	public static final String 		API_ENCODING			= "paas.encoding";
	public static final String 		API_DATE_FORMAT			= "paas.dateFormat";
	public static final String 		API_DEBUG_MODE			= "paas.debugMode";
	
	public static final String		DEFAULT_DATE_FORMAT		= "yyyy-MM-dd";
	public static final String		DEFAULT_DATE_TIME_FORMAT= "dd-MM-yyyy HH:mm:ss";

	public static final String		UTC_DATE_FORMAT			= "yyyy-MM-dd'T'HH:mm:ss'Z'";
	
	public static final TimeZone	UTC_TZ					= TimeZone.getTimeZone ("GMT");
	
	public static final Set BooleanValues				= new HashSet ();
	static {
		BooleanValues.add ("1"); BooleanValues.add ("y"); BooleanValues.add ("on"); BooleanValues.add ("yes"); BooleanValues.add ("true");
		BooleanValues.add ("0"); BooleanValues.add ("n"); BooleanValues.add ("off"); BooleanValues.add ("no"); BooleanValues.add ("false");
	}
	public static final Set TrueValues				= new HashSet ();
	static {
		TrueValues.add ("1"); TrueValues.add ("y"); TrueValues.add ("on"); TrueValues.add ("yes"); TrueValues.add ("true");
	}

	public static final Set FalseValues				= new HashSet ();
	static {
		FalseValues.add ("0"); FalseValues.add ("n"); FalseValues.add ("off"); FalseValues.add ("no"); FalseValues.add ("false");
	}
	
	//private static final String HMACSHA1 = "HMACSHA1";

	private static final String RandDigits = 
        	"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
	
	private static final String RandDigitsX = 
			RandDigits + "-+_/";
	
	private static final String RandNumbers = "123456789";
	
    private static final char[] DIGITS_LOWER =
        {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * Used to build output as Hex
     */
    private static final char[] DIGITS_UPPER =
        {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    
    private static final String NashornScript 		= "Script$Recompilation$";
    private static final String PlatformPath 		= "platform/core/";
    private static final String ApiResourcePath 	= "resoures/";
    
    private static final String EvalFile 			= "";
    private static final String UndefinedMessage 	= "undefined";
    private static final String TypeError 			= "TypeError: ";

   public static boolean isNullOrEmpty (String str) {
		if (str == null) {
			return true;
		}
		return str.trim ().isEmpty ();
	}
	
    public static String rand () {
    	return UUID.randomUUID ().toString ();
    }
    
    public static String pin (int length) {
    	return UUID (RandNumbers, length);
    }
    
    public static String oid () {
    	return OID.get ().toString ();
    }
    
    public static String UUID (int length) {
    	return UUID (RandDigits, length);
    }
    
    public static String UUID (String rd, int length) {
        if (length <= 0) {
            length = 10;
        }
        Random rand = new Random (System.nanoTime ());
        StringBuilder sb = new StringBuilder ();
        for (int i = 0; i < length; i++) {
            int pos = rand.nextInt (rd.length ());
            sb.append (String.valueOf (rd.charAt (pos)));
        }
        String s = sb.toString ();
        sb.setLength (0);
        return s;
    }
    /*
	public static String [] split (String str, String separator, boolean trim) {
		if (str == null) {
			return null;
		}
		if (separator == null || str.indexOf (separator) < 0) {
			return new String [] { trim ? str.trim () : str};
		}

		StringTokenizer st = new StringTokenizer (str, separator);
		
		String [] values = new String [st.countTokens ()];
		
		int pos = 0;
		while (st.hasMoreTokens ()) {
			values [pos++] = (trim ? st.nextToken ().trim () : st.nextToken ()) ;
		}
		
		return values;
	}
	*/

	public static String [] split (String str, String separator, boolean trim) {
		if (str == null) {
			return null;
		}
		if (separator == null || str.indexOf (separator) < 0) {
			return new String [] { trim ? str.trim () : str};
		}

		List list = new ArrayList ();
		
		int index = str.indexOf (separator);
		while (index >= 0) {
			String v = str.substring (0, index);
			list.add (trim ? v.trim () : v);
			str = str.substring (index + separator.length ());
			index = str.indexOf (separator);
		}
		
		list.add (trim ? str.trim () : str);
		
		String [] values = new String [list.size ()];
		list.toArray (values);
		
		return values;
	}

	public static String [] split (String str, String separator) {
		return split (str, separator, false);
	}    
    
    public static String join (String [] arr) {
    	return join (arr, COMMA);
    }
    
    public static String join (String [] arr, String sep) {
    	
    	if (arr == null || arr.length == 0) {
    		return null;
    	}
    	
    	StringBuilder sb = new StringBuilder ();
    	
    	for (int i = 0; i < arr.length; i++) {
    		sb.append (arr [i]);
    		if (i < (arr.length - 1)) {
    			sb.append (sep);
    		}
    	}
    	
    	String s = sb.toString ();
    	sb.setLength (0);
    	
    	return s;
    	
    }
    
    public static String join (List arr) {
    	return join (arr, COMMA);
    }
    
    public static String join (List arr, String sep) {
    	
    	if (arr == null || arr.isEmpty ()) {
    		return null;
    	}
    	
    	StringBuilder sb = new StringBuilder ();
    	
    	for (int i = 0; i < arr.size (); i++) {
    		sb.append (arr.get (i));
    		if (i < (arr.size () - 1)) {
    			sb.append (sep);
    		}
    	}
    	
    	String s = sb.toString ();
    	sb.setLength (0);
    	
    	return s;
    	
    }
    
    public static String [] moveLeft (String [] resource, int step) {
    	if (step < 1) {
    		return resource;
    	}
    	if (resource == null || step >= resource.length) {
    		return null;
    	}
    	
    	String [] result = new String [resource.length - step];
    	for (int i = 0; i < result.length; i++) {
    		result [i] = resource [i + step];
    	}
    	return result;
    }
    
    public static String [] moveRight (String [] resource, int step) {
    	if (step < 1) {
    		return resource;
    	}
    	if (resource == null || step >= resource.length) {
    		return null;
    	}
    	
    	String [] result = new String [resource.length - step];
    	for (int i = 0; i < result.length; i++) {
    		result [i] = resource [i];
    	}
    	return result;
    }
    
    public static String [] add (String [] a, String [] b) {
    	
    	if (a == null || a.length == 0) {
    		return b;
    	}
    	if (b == null || b.length == 0) {
    		return a;
    	}
    	
    	String [] sum = new String [a.length + b.length];
    	for (int i = 0; i < a.length; i++) {
    		sum [i] = a [i];
    	}
    	for (int i = 0; i < b.length; i++) {
    		sum [i + a.length] = b [i];
    	}
    	
    	return sum;
    	
    }
    
	public static boolean existsIn(String str, String[] searchIn) {
		return existsIn(str, searchIn, false);
	}
	
	public static boolean existsIn(String str, String[] searchIn, boolean ignoreCase) {
		boolean return_value = false;
		if (!ignoreCase) {
			for (int i = 0; i < searchIn.length; i++) {
				if (str.equals(searchIn[i])) {
					return_value = true;
					break;
				} else {
					return_value = false;
				}
			}
		} else {
			for (int i = 0; i < searchIn.length; i++) {
				if (str.equalsIgnoreCase(searchIn[i])) {
					return_value = true;
					break;
				} else {
					return_value = false;
				}
			}
		}
		return return_value;
	}

	public static String utc () {
		SimpleDateFormat formatter = new SimpleDateFormat (UTC_DATE_FORMAT);
		formatter.setTimeZone (UTC_TZ);
		return formatter.format (utcTime ());
	}

	public static Date utcTime () {
		return Calendar.getInstance (UTC_TZ).getTime ();
	}
    
	public static Date toDate (String date, String format) throws ParseException {
		return toDate (date, format, (Locale)null);
	}
	
	public static Date toDate (String date, String format, Locale locale) throws ParseException {
        return toDate (date, format, locale, null);
    }

	public static Date toDate (String date, String format, TimeZone tz) throws ParseException {
        return toDate (date, format, null, tz);
    }

	public static Date toUTC (String date) throws ParseException {
        return toDate (date, UTC_DATE_FORMAT, UTC_TZ);
    }

	public static Date toDate (String date, String format, Locale locale, TimeZone tz) throws ParseException {
        SimpleDateFormat formatter = null;
        if (locale != null) {
        	formatter = new SimpleDateFormat (format, locale);
        } else {
        	formatter = new SimpleDateFormat (format);
        }
        formatter.setLenient (false);
        if (tz == null) {
        	tz = TimeZone.getDefault ();
        }
        formatter.setTimeZone (tz);
        return formatter.parse (date);
    }

	public static String toUTC (Date date) {
        return toString (date, UTC_DATE_FORMAT, UTC_TZ);
    }
	
	public static String toString (Date date, String format) {
        return toString (date, format, (Locale)null);
    }
	
	public static String toString (Date date, String format, TimeZone tz) {
        return toString (date, format, null, tz);
    }
	
	public static String toString (Date date, String format, Locale locale) {
        return toString (date, format, locale, null);
    }
	
	public static String toString (Date date, String format, Locale locale, TimeZone tz) {
        SimpleDateFormat formatter = null;
        if (locale != null) {
        	formatter = new SimpleDateFormat (format, locale);
        } else {
        	formatter = new SimpleDateFormat (format);
        }
        if (tz == null) {
        	tz = TimeZone.getDefault ();
        }
        formatter.setTimeZone (tz);
        return formatter.format (date);
    }
	
	public static Throwable getRootCause (Throwable th) {
		Throwable cause = th;
		while (true) {
			Throwable c = cause.getCause ();
			if (c == null) {
				return cause;
			}
			cause = c;
		}
	}
	
	public static void printTree (Throwable th) {
		Throwable cause = th;
		while (true) {
			System.out.println (cause.getClass ().getName () + " > " + cause.getMessage());
			Throwable c = cause.getCause ();
			if (c == null) {
				return;
			}
			cause = c;
		}
	}
	
	public static String toString (Throwable th) {
		if (th == null) {
			return null;
		}
		if (!isDebugMode ()) {
			String message = th.getMessage ();
			if (message == null) {
				StackTraceElement ste = th.getStackTrace () [0];
				message = 
					th.getClass ().getSimpleName () + Lang.GREATER + Lang.SPACE + 
					ste.getClassName () + ste.getMethodName () + ste.getLineNumber ();
			}
			return message;
		}
		StringWriter sw = new StringWriter ();
		PrintWriter pw = new PrintWriter (sw);
		th.printStackTrace (pw);
		
		return sw.toString ();
	}
	
	public static String [] toMessage (Throwable th) {
		if (th == null) {
			return null;
		}
		String [] arr = new String [2];
		
		String message = th.getMessage ();
		if (message == null) {
			StackTraceElement ste = th.getStackTrace () [0];
			message = 
				th.getClass ().getSimpleName () + Lang.GREATER + Lang.SPACE + 
				ste.getClassName () + Lang.SPACE + ", Method: " + ste.getMethodName () + ", Line: " + ste.getLineNumber ();
		}

		arr [0] = message;
		
		if (isDebugMode ()) {
			StringWriter sw = new StringWriter ();
			PrintWriter pw = new PrintWriter (sw);
			th.printStackTrace (pw);
			
			arr [1] = sw.toString ();
		} else {
			arr [1] = Lang.BLANK;
		}
		
		return arr;
	}
	
	public static JsonObject toError (Throwable th) {
		if (th == null) {
			return null;
		}
		
		Throwable first = th;
		
		th = Lang.getRootCause (th);

		String message = th.getMessage ();
		if (message == null) {
			StackTraceElement ste = th.getStackTrace () [0];
			message = 
				th.getClass ().getSimpleName () + Lang.GREATER + Lang.SPACE + 
				ste.getClassName () + Lang.SPACE + ", Method: " + ste.getMethodName () + ", Line: " + ste.getLineNumber ();
		}
		
		JsonObject error = new JsonObject ();
		error.set (ApiResponse.Error.Message, message);
		
		if (!Lang.isDebugMode ()) {
			return error;
		}
		
		JsonArray trace = new JsonArray ();
		error.set (ApiResponse.Error.Trace, trace);
		
		if (th instanceof NashornException) {
			if (UndefinedMessage.equals (message)) {
				error.set (ApiResponse.Error.Message, UndefinedMessage + " variable");
			} else if (message.startsWith (TypeError)) {
				error.set (ApiResponse.Error.Message, Lang.replace (message, TypeError, Lang.BLANK));
			}
			readNashornError (th, first, trace);
			return error;
		} 
		
		StackTraceElement [] stack = th.getStackTrace ();
		for (StackTraceElement line : stack) {
			JsonObject oLine = new JsonObject ();
			trace.add (oLine);
			
			oLine.set (ApiResponse.Error.Line, line.getLineNumber ());
			oLine.set (ApiResponse.Error.Function, line.getMethodName ());
			
			String className = line.getClassName ();

			int indeOfNashornScript = className.indexOf (NashornScript);
			if (indeOfNashornScript > 0) {
				String file = line.getFileName ();
				
				// if  the error is coming from the platform core scripts
				int indexOfPath = file.indexOf (PlatformPath); 
				if (indexOfPath <= 0) {
					indexOfPath = file.indexOf (ApiResourcePath); 
				}
				if (indexOfPath > 0) {
					file = file.substring (indexOfPath);
				}
				oLine.set (ApiResponse.Error.File, file);
				
				// break here
				break;
				
			} else {
				int indexOfDot = className.lastIndexOf (Lang.DOT); 
				if (indexOfDot > 0) {
					className = className.substring (indexOfDot + 1);
				}
				oLine.set (ApiResponse.Error.Clazz, className);
			}
			
		}
		
		return error;
	}
	
	public static String encode (String value) {
		try {
			return URLEncoder.encode (value, Encodings.UTF8);
		} catch (UnsupportedEncodingException e) {
			return value;
		}
	}
	
	public static String decode (String value) {
		try {
			return URLDecoder.decode (value, Encodings.UTF8);
		} catch (UnsupportedEncodingException e) {
			return value;
		}
	}
	
	public static String replace (String source, String os, String ns) {
        if (source == null) {
            return null;
        }
        if (os == null || ns == null) {
            return source;
        }
        int i = 0;
        // Make sure that oldString appears at least once before doing any processing.
        if ((i = source.indexOf(os, i)) >= 0) {
            // Use char []'s, as they are more efficient to deal with.
            char[] sourceArray = source.toCharArray();
            char[] nsArray = ns.toCharArray();
            int oLength = os.length();
            StringBuilder buf = new StringBuilder (sourceArray.length);
            buf.append (sourceArray, 0, i).append(nsArray);
            i += oLength;
            int j = i;
            // Replace all remaining instances of oldString with newString.
            while ((i = source.indexOf(os, i)) > 0) {
                buf.append (sourceArray, j, i - j).append(nsArray);
                i += oLength;
                j = i;
            }
            buf.append (sourceArray, j, sourceArray.length - j);
            source = buf.toString();
            buf.setLength (0);
        }
        return source;
	}

	public static boolean like (String str, String expr) {
		String regex = quotemeta(expr);
		regex = regex.replace (UNDERSCORE, DOT).replace (PERCENT, ".*?");
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE
				| Pattern.DOTALL);
		return p.matcher (str).matches ();
	}
	
	public interface VariableResolver {
		String resolve (String namespace, String name);
	}
	
	public static String resolve (String exp, String expStart, String expEnd, VariableResolver resolver) {
		if (exp == null) {
			return null;
		}
		
		int indexOfStart = exp.indexOf (expStart);
		while (indexOfStart > -1) {
			int indexOfEnd = exp.indexOf (expEnd, indexOfStart + expStart.length ());
			if (indexOfEnd <= -1) {
				indexOfStart = exp.indexOf (expStart, indexOfStart + expStart.length ());
				continue;
			}
			
			String prop = exp.substring (indexOfStart + expStart.length (), indexOfEnd);
			
			String ns = null;
			String var = prop;
			
			int indexOfDot = prop.indexOf (Lang.DOT);
			if (indexOfDot > 0) {
				ns 	= prop.substring (0, indexOfDot);
				var = prop.substring (indexOfDot + 1);
			}
			
			String value = resolver.resolve (ns, var);
			
			exp = replace (exp, expStart + prop + expEnd, value);
			
			indexOfStart = exp.indexOf (expStart, indexOfStart + expStart.length ());
		}
		
		return exp;
	}
	
	public static String resolve (String exp, VariableResolver resolver) {
		return resolve (exp, ExpStart, ExpEnd, resolver);
	}

	private static String quotemeta (String s) {
		if (s == null) {
			throw new IllegalArgumentException("String cannot be null");
		}

		int len = s.length ();
		if (len == 0) {
			return Lang.BLANK;
		}

		StringBuilder sb = new StringBuilder(len * 2);
		for (int i = 0; i < len; i++) {
			char c = s.charAt(i);
			if ("[](){}.*+?$^|#\\".indexOf(c) != -1) {
				sb.append (Lang.BACKSLASH);
			}
			sb.append(c);
		}
		return sb.toString();
	}

	public static String [] keys () throws Exception {
		return keys (30, 40);
	}
	
	public static String [] keys (int akl, int skl) throws Exception {
		return new String [] { UUID (RandDigits, akl).toUpperCase (), UUID (RandDigitsX, skl) };
	}

	public static void setDebugMode (boolean debugMode) {
		System.setProperty (API_DEBUG_MODE, String.valueOf (debugMode));
	}

	public static boolean isDebugMode () {
		String dm = System.getProperty (API_DEBUG_MODE);
		if (dm == null) {
			return false;
		}
		return TrueValues.contains (dm);
	}
	
	/*
	private static String hash (byte [] key, String encoding) throws Exception {
		return new String (Base64.encodeBase64 (key), encoding).trim ();
	}
	*/
	
    public static byte[] decodeHex (final char[] data) throws Exception {

        final int len = data.length;

        if ((len & 0x01) != 0) {
            throw new Exception ("Odd number of characters.");
        }

        final byte[] out = new byte[len >> 1];

        // two characters form the hex value.
        for (int i = 0, j = 0; j < len; i++) {
            int f = toDigit(data[j], j) << 4;
            j++;
            f = f | toDigit(data[j], j);
            j++;
            out[i] = (byte) (f & 0xFF);
        }

        return out;
    }

    public static char[] encodeHex (final byte[] data) {
        return encodeHex(data, true);
    }

    public static char[] encodeHex (final byte[] data, final boolean toLowerCase) {
        return encodeHex (data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
     * The returned array will be double the length of the passed array, as it takes two characters to represent any
     * given byte.
     *
     * @param data
     *            a byte[] to convert to Hex characters
     * @param toDigits
     *            the output alphabet
     * @return A char[] containing hexadecimal characters
     * @since 1.4
     */
    private static char[] encodeHex(final byte[] data, final char[] toDigits) {
        final int l = data.length;
        final char[] out = new char[l << 1];
        // two characters form the hex value.
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }
	
    private static int toDigit (final char ch, final int index) throws Exception {
        final int digit = Character.digit(ch, 16);
        if (digit == -1) {
            throw new Exception ("Illegal hexadecimal character " + ch + " at index " + index);
        }
        return digit;
    }
    
	private static void readNashornError (Throwable err, Throwable first, JsonArray trace) {
        NashornException exc = (NashornException) err;
        
        StackTraceElement [] stack = exc.getStackTrace ();
		for (StackTraceElement line : stack) {
			String className = line.getClassName ();
			
			int indeOfNashornScript = className.indexOf (NashornScript);
			if (indeOfNashornScript < 0) {
				continue;
			}
			
	        JsonObject oLine = new JsonObject ();
	        
	        String originalScript = getScriptFile (first);
	        
	        String file = line.getFileName ();
	        
	        if (EvalFile.equals (file)) {
	        	file = originalScript;
	        } else {
	            file = removeScriptPath (file);
	        }
			
			oLine.set (ApiResponse.Error.File, file);
	        
	        oLine.set (ApiResponse.Error.Line, line.getLineNumber ());
	        
	        trace.add (0, oLine);
		}
		
	}
	
	private static String getScriptFile (Throwable first) {
		Throwable cause = first;
		while (true) {
			if (cause instanceof ScriptingEngineException) {
				return removeScriptPath (((ScriptingEngineException)cause).getScript ());
			}
			Throwable c = cause.getCause ();
			if (c == null) {
				return null;
			}
			cause = c;
		}
	} 
	
	private static String removeScriptPath (String file) {
		if (file == null) {
			return null;
		}
		int indexOfPath = file.indexOf (PlatformPath); 
		if (indexOfPath <= 0) {
			indexOfPath = file.indexOf (ApiResourcePath); 
		}
		if (indexOfPath > 0) {
			file = file.substring (indexOfPath);
		}
		return file;
	}
	
	public static String [] toArray (Set set1, Set set2) {
		if (set1 == null) {
			return null;
		}
		if (set1.isEmpty ()) {
			return new String [] {};
		}
		
		String [] array = new String [set1.size ()]; 
		
		set1.toArray (array);
		
		if (set2 != null && !set2.isEmpty ()) {
			String [] a2 = new String [set2.size ()]; 
			set2.toArray (a2);
			array = Lang.add (array, a2);
		}
		
		return array;
	}
	
	public static String capitalizeFirst (String name) {
		if (Lang.isNullOrEmpty (name)) {
			return name;
		}
		if (name.length () == 1) {
			return name.toUpperCase ();
		}
		return name.substring (0, 1).toUpperCase () + name.substring (1);
	}
	
	public static String pluralize (String name) {
		if (Lang.isNullOrEmpty (name)) {
			return name;
		}
		return (name.endsWith ("y") ? (name.substring (0, name.length () - 1) + "ies") : name + "s");
	}
	
	public static String singularize (String name) {
		if (Lang.isNullOrEmpty (name) || !name.endsWith ("s")) {
			return name;
		}
		return (name.endsWith ("ies") ? (name.substring (0, name.length () - 3) + "y") : name.substring (0, name.length () - 1));
	}
	
	public static boolean wmatches (String wildcard, String value) {
		WildcardMatcher matcher = new WildcardMatcher (WildcardCompiler.compile (wildcard), value);
		return matcher.find ();
	}
	
	public static void setTimeout (Runnable runnable, int delay){
	    new Thread(() -> {
	        try {
	            Thread.sleep (delay);
	            runnable.run ();
	        } catch (Exception e){
	            // Ignore
	        }
	    }).start();
	}
	
    public static Object template (String template, JsonObject data, boolean withScripting) {
    	if (Lang.isNullOrEmpty (template) || Json.isNullOrEmpty (data)) {
    		return template;
    	}
    	ExpressionCompiler compiler = withScripting ? ScriptedExpressionCompiler : ExpressionCompiler;
    	return compiler.compile (template, null).eval (new BasicVariableResolver (data));
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy