mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 17:13:21 +00:00 
			
		
		
		
	GUAC-340: Add TokenFilter class which performs arbitrary token replacement.
This commit is contained in:
		| @@ -0,0 +1,213 @@ | ||||
| /* | ||||
|  * Copyright (C) 2015 Glyptodon LLC | ||||
|  *  | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  *  | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  *  | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package org.glyptodon.guacamole.token; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| /** | ||||
|  * Filtering object which replaces tokens of the form "${TOKEN_NAME}" with | ||||
|  * their corresponding values. Unknown tokens are not replaced. If TOKEN_NAME | ||||
|  * is a valid token, the literal value "${TOKEN_NAME}" can be included by using | ||||
|  * "$${TOKEN_NAME}". | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class TokenFilter { | ||||
|  | ||||
|     /** | ||||
|      * Regular expression which matches individual tokens, with additional | ||||
|      * capturing groups for convenient retrieval of leading text, the possible | ||||
|      * escape character preceding the token, the name of the token, and the | ||||
|      * entire token itself. | ||||
|      */ | ||||
|     private final Pattern tokenPattern = Pattern.compile("(.*?)(^|.)(\\$\\{([A-Za-z0-9_]*)\\})"); | ||||
|  | ||||
|     /** | ||||
|      * The index of the capturing group within tokenPattern which matches | ||||
|      * non-token text preceding a possible token. | ||||
|      */ | ||||
|     private static final int LEADING_TEXT_GROUP = 1; | ||||
|  | ||||
|     /** | ||||
|      * The index of the capturing group within tokenPattern which matches the | ||||
|      * character immediately preceding a possible token, possibly denoting that | ||||
|      * the token should instead be interpreted as a literal. | ||||
|      */ | ||||
|     private static final int ESCAPE_CHAR_GROUP = 2; | ||||
|  | ||||
|     /** | ||||
|      * The index of the capturing group within tokenPattern which matches the | ||||
|      * entire token, including the leading "${" and terminating "}" strings. | ||||
|      */ | ||||
|     private static final int TOKEN_GROUP = 3; | ||||
|  | ||||
|     /** | ||||
|      * The index of the capturing group within tokenPattern which matches only | ||||
|      * the token name contained within the "${" and "}" strings. | ||||
|      */ | ||||
|     private static final int TOKEN_NAME_GROUP = 4; | ||||
|      | ||||
|     /** | ||||
|      * The values of all known tokens. | ||||
|      */ | ||||
|     private final Map<String, String> tokenValues = new HashMap<String, String>(); | ||||
|  | ||||
|     /** | ||||
|      * Sets the token having the given name to the given value. Any existing | ||||
|      * value for that token is replaced. | ||||
|      * | ||||
|      * @param name | ||||
|      *     The name of the token to set. | ||||
|      * | ||||
|      * @param value | ||||
|      *     The value to set the token to. | ||||
|      */ | ||||
|     public void setToken(String name, String value) { | ||||
|         tokenValues.put(name, value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the value of the token with the given name, or null if no such | ||||
|      * token has been set. | ||||
|      * | ||||
|      * @param name | ||||
|      *     The name of the token to return. | ||||
|      *  | ||||
|      * @return | ||||
|      *     The value of the token with the given name, or null if no such | ||||
|      *     token exists. | ||||
|      */ | ||||
|     public String getToken(String name) { | ||||
|         return tokenValues.get(name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes the value of the token with the given name. If no such token | ||||
|      * exists, this function has no effect. | ||||
|      * | ||||
|      * @param name | ||||
|      *     The name of the token whose value should be removed. | ||||
|      */ | ||||
|     public void unsetToken(String name) { | ||||
|         tokenValues.remove(name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a map of all tokens, with each key being a token name, and each | ||||
|      * value being the corresponding token value. Changes to this map will | ||||
|      * directly affect the tokens associated with this filter. | ||||
|      * | ||||
|      * @return | ||||
|      *     A map of all token names and their corresponding values. | ||||
|      */ | ||||
|     public Map<String, String> getTokens() { | ||||
|         return tokenValues; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Replaces all current token values with the contents of the given map, | ||||
|      * where each map key represents a token name, and each map value | ||||
|      * represents a token value. | ||||
|      * | ||||
|      * @param tokens | ||||
|      *     A map containing the token names and corresponding values to | ||||
|      *     assign. | ||||
|      */ | ||||
|     public void setTokens(Map<String, String> tokens) { | ||||
|         tokenValues.clear(); | ||||
|         tokenValues.putAll(tokens); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Filters the given string, replacing any tokens with their corresponding | ||||
|      * values. | ||||
|      * | ||||
|      * @param input | ||||
|      *     The string to filter. | ||||
|      * | ||||
|      * @return | ||||
|      *     A copy of the input string, with any tokens replaced with their | ||||
|      *     corresponding values. | ||||
|      */ | ||||
|     public String filter(String input) { | ||||
|  | ||||
|         StringBuilder output = new StringBuilder(); | ||||
|         Matcher tokenMatcher = tokenPattern.matcher(input); | ||||
|  | ||||
|         // Track last regex match | ||||
|         int endOfLastMatch = 0; | ||||
|  | ||||
|         // For each possible token | ||||
|         while (tokenMatcher.find()) { | ||||
|  | ||||
|             // Pull possible leading text and first char before possible token | ||||
|             String literal = tokenMatcher.group(LEADING_TEXT_GROUP); | ||||
|             String escape = tokenMatcher.group(ESCAPE_CHAR_GROUP); | ||||
|  | ||||
|             // Append leading non-token text | ||||
|             output.append(literal); | ||||
|  | ||||
|             // If char before token is '$', the token itself is escaped | ||||
|             if ("$".equals(escape)) { | ||||
|                 String notToken = tokenMatcher.group(TOKEN_GROUP); | ||||
|                 output.append(notToken); | ||||
|             } | ||||
|  | ||||
|             // If char is not '$', interpret as a token | ||||
|             else { | ||||
|  | ||||
|                 // The char before the token, if any, is a literal | ||||
|                 output.append(escape); | ||||
|  | ||||
|                 // Pull token value | ||||
|                 String tokenName = tokenMatcher.group(TOKEN_NAME_GROUP); | ||||
|                 String tokenValue = getToken(tokenName); | ||||
|  | ||||
|                 // If token is unknown, interpret as literal | ||||
|                 if (tokenValue == null) { | ||||
|                     String notToken = tokenMatcher.group(TOKEN_GROUP); | ||||
|                     output.append(notToken); | ||||
|                 } | ||||
|  | ||||
|                 // Otherwise, substitute value | ||||
|                 else | ||||
|                     output.append(tokenValue); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // Update last regex match | ||||
|             endOfLastMatch = tokenMatcher.end(); | ||||
|              | ||||
|         } | ||||
|  | ||||
|         // Append any remaining non-token text | ||||
|         output.append(input.substring(endOfLastMatch)); | ||||
|          | ||||
|         return output.toString(); | ||||
|         | ||||
|     } | ||||
|      | ||||
| } | ||||
		Reference in New Issue
	
	Block a user