| // Copyright (C) 2011 Chan Wai Shing | |
| // | |
| // 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 prettify.parser; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.TreeMap; | |
| import java.util.regex.Matcher; | |
| import java.util.regex.Pattern; | |
| /** | |
| * Common Utilities. | |
| * Some of the functions are port from JavaScript. | |
| * | |
| * @author Chan Wai Shing <cws1989@gmail.com> | |
| */ | |
| public class Util { | |
| protected Util() { | |
| } | |
| /** | |
| * Treat a variable as an boolean in JavaScript style. Note this function can | |
| * only handle string, integer and boolean currently. All other data type, if | |
| * null, return false, not null return true. | |
| * | |
| * @param var the variable to get value from | |
| * @return the boolean value | |
| */ | |
| public static Boolean getVariableValueAsBoolean(Object var) { | |
| Boolean returnResult = null; | |
| if (var == null) { | |
| returnResult = false; | |
| } else if (var instanceof String) { | |
| returnResult = !((String) var).isEmpty(); | |
| } else if (var instanceof Integer) { | |
| returnResult = ((Integer) var) != 0; | |
| } else if (var instanceof Boolean) { | |
| returnResult = (Boolean) var; | |
| } else { | |
| returnResult = true; | |
| } | |
| return returnResult; | |
| } | |
| /** | |
| * Treat a variable as an integer in JavaScript style. Note this function can | |
| * only handle integer and boolean currently. | |
| * | |
| * @param var the variable to get value from | |
| * @return the integer value | |
| * @throws IllegalArgumentException the data type of {@code var} is neither | |
| * integer nor boolean. | |
| */ | |
| public static Integer getVariableValueAsInteger(Object var) { | |
| if (var == null) { | |
| throw new NullPointerException("argument 'var' cannot be null"); | |
| } | |
| Integer returnResult = -1; | |
| if (var instanceof Integer) { | |
| returnResult = (Integer) var; | |
| } else if (var instanceof Boolean) { | |
| // Javascript treat true as 1 | |
| returnResult = (Boolean) var ? 1 : 0; | |
| } else { | |
| throw new IllegalArgumentException("'var' is neither integer nor boolean"); | |
| } | |
| return returnResult; | |
| } | |
| /** | |
| * Get all the matches for {@code string} compiled by {@code pattern}. If | |
| * {@code isGlobal} is true, the return results will only include the | |
| * group 0 matches. It is similar to string.match(regexp) in JavaScript. | |
| * | |
| * @param pattern the regexp | |
| * @param string the string | |
| * @param isGlobal similar to JavaScript /g flag | |
| * | |
| * @return all matches | |
| */ | |
| public static String[] match(Pattern pattern, String string, boolean isGlobal) { | |
| if (pattern == null) { | |
| throw new NullPointerException("argument 'pattern' cannot be null"); | |
| } | |
| if (string == null) { | |
| throw new NullPointerException("argument 'string' cannot be null"); | |
| } | |
| List<String> matchesList = new ArrayList<String>(); | |
| Matcher matcher = pattern.matcher(string); | |
| while (matcher.find()) { | |
| matchesList.add(matcher.group(0)); | |
| if (!isGlobal) { | |
| for (int i = 1, iEnd = matcher.groupCount(); i <= iEnd; i++) { | |
| matchesList.add(matcher.group(i)); | |
| } | |
| } | |
| } | |
| return matchesList.toArray(new String[matchesList.size()]); | |
| } | |
| /** | |
| * Test whether the {@code string} has at least one match by | |
| * {@code pattern}. | |
| * | |
| * @param pattern the regexp | |
| * @param string the string to test | |
| * | |
| * @return true if at least one match, false if no match | |
| */ | |
| public static boolean test(Pattern pattern, String string) { | |
| if (pattern == null) { | |
| throw new NullPointerException("argument 'pattern' cannot be null"); | |
| } | |
| if (string == null) { | |
| throw new NullPointerException("argument 'string' cannot be null"); | |
| } | |
| return pattern.matcher(string).find(); | |
| } | |
| /** | |
| * Join the {@code strings} into one string. | |
| * | |
| * @param strings the string list to join | |
| * | |
| * @return the joined string | |
| */ | |
| public static String join(List<String> strings) { | |
| if (strings == null) { | |
| throw new NullPointerException("argument 'strings' cannot be null"); | |
| } | |
| return join(strings.toArray(new String[strings.size()])); | |
| } | |
| /** | |
| * Join the {@code strings} into one string with {@code delimiter} in | |
| * between. | |
| * | |
| * @param strings the string list to join | |
| * @param delimiter the delimiter | |
| * | |
| * @return the joined string | |
| */ | |
| public static String join(List<String> strings, String delimiter) { | |
| if (strings == null) { | |
| throw new NullPointerException("argument 'strings' cannot be null"); | |
| } | |
| return join(strings.toArray(new String[strings.size()]), delimiter); | |
| } | |
| /** | |
| * Join the {@code strings} into one string. | |
| * | |
| * @param strings the string list to join | |
| * | |
| * @return the joined string | |
| */ | |
| public static String join(String[] strings) { | |
| return join(strings, null); | |
| } | |
| /** | |
| * Join the {@code strings} into one string with {@code delimiter} in | |
| * between. It is similar to RegExpObject.test(string) in JavaScript. | |
| * | |
| * @param strings the string list to join | |
| * @param delimiter the delimiter | |
| * | |
| * @return the joined string | |
| */ | |
| public static String join(String[] strings, String delimiter) { | |
| if (strings == null) { | |
| throw new NullPointerException("argument 'strings' cannot be null"); | |
| } | |
| StringBuilder sb = new StringBuilder(); | |
| if (strings.length != 0) { | |
| sb.append(strings[0]); | |
| for (int i = 1, iEnd = strings.length; i < iEnd; i++) { | |
| if (delimiter != null) { | |
| sb.append(delimiter); | |
| } | |
| sb.append(strings[i]); | |
| } | |
| } | |
| return sb.toString(); | |
| } | |
| /** | |
| * Remove identical adjacent tags from {@code decorations}. | |
| * | |
| * @param decorations see {@link prettify.parser.Job#decorations} | |
| * @param source the source code | |
| * | |
| * @return the {@code decorations} after treatment | |
| * | |
| * @throws IllegalArgumentException the size of {@code decoration} is not | |
| * a multiple of 2 | |
| */ | |
| public static List<Object> removeDuplicates(List<Object> decorations, String source) { | |
| if (decorations == null) { | |
| throw new NullPointerException("argument 'decorations' cannot be null"); | |
| } | |
| if (source == null) { | |
| throw new NullPointerException("argument 'source' cannot be null"); | |
| } | |
| if ((decorations.size() & 0x1) != 0) { | |
| throw new IllegalArgumentException("the size of argument 'decorations' should be a multiple of 2"); | |
| } | |
| List<Object> returnList = new ArrayList<Object>(); | |
| // use TreeMap to remove entrys with same pos | |
| Map<Integer, Object> orderedMap = new TreeMap<Integer, Object>(); | |
| for (int i = 0, iEnd = decorations.size(); i < iEnd; i += 2) { | |
| orderedMap.put((Integer) decorations.get(i), decorations.get(i + 1)); | |
| } | |
| // remove adjacent style | |
| String previousStyle = null; | |
| for (Integer pos : orderedMap.keySet()) { | |
| String style = (String) orderedMap.get(pos); | |
| if (previousStyle != null && previousStyle.equals(style)) { | |
| continue; | |
| } | |
| returnList.add(pos); | |
| returnList.add(style); | |
| previousStyle = style; | |
| } | |
| // remove last zero length tag | |
| int returnListSize = returnList.size(); | |
| if (returnListSize >= 4 && returnList.get(returnListSize - 2).equals(source.length())) { | |
| returnList.remove(returnListSize - 2); | |
| returnList.remove(returnListSize - 2); | |
| } | |
| return returnList; | |
| } | |
| } |