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

com.phloc.web.fileupload.ParameterParser Maven / Gradle / Ivy

/**
 * Copyright (C) 2006-2015 phloc systems
 * http://www.phloc.com
 * office[at]phloc[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phloc.web.fileupload;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.phloc.commons.annotations.ReturnsMutableCopy;
import com.phloc.commons.collections.ArrayHelper;
import com.phloc.commons.string.StringHelper;

/**
 * A simple parser intended to parse sequences of name/value pairs. Parameter
 * values are exptected to be enclosed in quotes if they contain unsafe
 * characters, such as '=' characters or separators. Parameter values are
 * optional and can be omitted.
 * 

* param1 = value; param2 = "anything goes; really"; param3 *

* * @author Oleg Kalnichevski */ public final class ParameterParser { /** * String to be parsed. */ private char [] m_aChars; /** * Current position in the string. */ private int m_nPos = 0; /** * Maximum position in the string. */ private int m_nLen = 0; /** * Start of a token. */ private int m_nIndex1 = 0; /** * End of a token. */ private int m_nIndex2 = 0; /** * Whether names stored in the map should be converted to lower case. */ private boolean m_bLowerCaseNames = false; /** * Default ParameterParser constructor. */ public ParameterParser () {} /** * Are there any characters left to parse? * * @return true if there are unparsed characters, false * otherwise. */ private boolean _hasChar () { return m_nPos < m_nLen; } /** * A helper method to process the parsed token. This method removes leading * and trailing blanks as well as enclosing quotation marks, when necessary. * * @param quoted * true if quotation marks are expected, false * otherwise. * @return the token */ @Nullable private String _getToken (final boolean quoted) { // Trim leading white spaces while (m_nIndex1 < m_nIndex2 && Character.isWhitespace (m_aChars[m_nIndex1])) { m_nIndex1++; } // Trim trailing white spaces while (m_nIndex2 > m_nIndex1 && Character.isWhitespace (m_aChars[m_nIndex2 - 1])) { m_nIndex2--; } // Strip away quotation marks if necessary if (quoted) { if ((m_nIndex2 - m_nIndex1) >= 2 && m_aChars[m_nIndex1] == '"' && m_aChars[m_nIndex2 - 1] == '"') { m_nIndex1++; m_nIndex2--; } } String result = null; if (m_nIndex2 > m_nIndex1) { result = new String (m_aChars, m_nIndex1, m_nIndex2 - m_nIndex1); } return result; } /** * Parses out a token until any of the given terminators is encountered. * * @param cTerminator1 * the first terminating character. Any when encountered signify the * end of the token * @param cTerminator2 * the second terminating character. Any when encountered signify the * end of the token * @return the token */ @Nullable private String _parseToken (final char cTerminator1, final char cTerminator2) { char ch; m_nIndex1 = m_nPos; m_nIndex2 = m_nPos; while (_hasChar ()) { ch = m_aChars[m_nPos]; if (ch == cTerminator1 || ch == cTerminator2) break; m_nIndex2++; m_nPos++; } return _getToken (false); } /** * Parses out a token until any of the given terminators is encountered * outside the quotation marks. * * @param cTerminator * the terminating character. Any of these characters when encountered * outside the quotation marks signify the end of the token * @return the token */ @Nullable private String _parseQuotedToken (final char cTerminator) { char ch; m_nIndex1 = m_nPos; m_nIndex2 = m_nPos; boolean bQuoted = false; boolean bCharEscaped = false; while (_hasChar ()) { ch = m_aChars[m_nPos]; if (!bQuoted && cTerminator == ch) break; if (!bCharEscaped && ch == '"') bQuoted = !bQuoted; bCharEscaped = (!bCharEscaped && ch == '\\'); m_nIndex2++; m_nPos++; } return _getToken (true); } /** * Returns true if parameter names are to be converted to lower case * when name/value pairs are parsed. * * @return true if parameter names are to be converted to lower case * when name/value pairs are parsed. Otherwise returns false */ public boolean isLowerCaseNames () { return m_bLowerCaseNames; } /** * Sets the flag if parameter names are to be converted to lower case when * name/value pairs are parsed. * * @param b * true if parameter names are to be converted to lower case * when name/value pairs are parsed. false otherwise. */ public void setLowerCaseNames (final boolean b) { m_bLowerCaseNames = b; } /** * Extracts a map of name/value pairs from the given string. Names are * expected to be unique. Multiple separators may be specified and the * earliest found in the input string is used. * * @param sStr * the string that contains a sequence of name/value pairs * @param aSeparators * the name/value pairs separators * @return a map of name/value pairs */ @Nonnull @ReturnsMutableCopy public Map parse (@Nullable final String sStr, @Nullable final char [] aSeparators) { if (ArrayHelper.isEmpty (aSeparators)) return new HashMap (); char cSep = aSeparators[0]; if (sStr != null) { // Find the first separator to use int idx = sStr.length (); for (final char cSep2 : aSeparators) { final int tmp = sStr.indexOf (cSep2); if (tmp != -1 && tmp < idx) { idx = tmp; cSep = cSep2; } } } return parse (sStr, cSep); } /** * Extracts a map of name/value pairs from the given string. Names are * expected to be unique. * * @param str * the string that contains a sequence of name/value pairs * @param separator * the name/value pairs separator * @return a map of name/value pairs */ @Nonnull @ReturnsMutableCopy public Map parse (@Nullable final String str, final char separator) { final HashMap params = new HashMap (); if (str != null) { final char [] chars = str.toCharArray (); m_aChars = chars; m_nPos = 0; m_nLen = str.length (); String sParamName = null; String sParamValue = null; while (_hasChar ()) { sParamName = _parseToken ('=', separator); sParamValue = null; if (_hasChar () && chars[m_nPos] == '=') { m_nPos++; // skip '=' sParamValue = _parseQuotedToken (separator); } if (_hasChar () && chars[m_nPos] == separator) { m_nPos++; // skip separator } if (StringHelper.hasText (sParamName)) { if (m_bLowerCaseNames) sParamName = sParamName.toLowerCase (Locale.US); params.put (sParamName, sParamValue); } } } return params; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy