/* * #%L * Wisdom-Framework * %% * Copyright (C) 2013 - 2014 Wisdom Framework * %% * 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. * #L% */ package org.wisdom.framework.osgi; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import java.util.ArrayList; import java.util.List; /** * A tokenizer used to parse manifest header. * Taken from BND code. */ public class QuotedTokenizer { String string; int index = 0; String separators; boolean returnTokens; String peek; char separator; /** * Creates a tokenizer. * @param string the string to parse * @param separators the separators * @param returnTokens whether or not tokens are returned */ public QuotedTokenizer(String string, String separators, boolean returnTokens) { this.string = Preconditions.checkNotNull(string); Preconditions.checkArgument(!Strings.isNullOrEmpty(separators)); this.separators = separators; this.returnTokens = returnTokens; } /** * Creates a tokenizer. * @param string the string to parse * @param separators the separators */ public QuotedTokenizer(String string, String separators) { this(string, separators, false); } /** * Retrieve next token. * @param separators the separators * @return the next token. */ public String nextToken(String separators) { separator = 0; if (peek != null) { String tmp = peek; peek = null; return tmp; } if (index == string.length()) { return null; } StringBuilder sb = new StringBuilder(); boolean hadstring = false; // means no further trimming boolean validspace = false; // means include spaces while (index < string.length()) { char c = string.charAt(index++); if (Character.isWhitespace(c)) { if (index == string.length()) { break; } if (validspace) { sb.append(c); } continue; } if (separators.indexOf(c) >= 0) { if (returnTokens) { peek = Character.toString(c); } else { separator = c; } break; } switch (c) { case '"': case '\'': hadstring = true; quotedString(sb, c); // skip remaining space validspace = false; break; default: sb.append(c); validspace = true; } } String result = sb.toString(); if (!hadstring) { result = result.trim(); } if (result.length() == 0 && index == string.length()) { return null; } return result; } /** * Retrieves next token. * @return the token */ public String nextToken() { return nextToken(separators); } private void quotedString(StringBuilder sb, char c) { char quote = c; while (index < string.length()) { c = string.charAt(index++); if (c == quote) { break; } if (c == '\\' && index < string.length()) { char cc = string.charAt(index++); if (cc != quote) sb.append("\\"); c = cc; } sb.append(c); } } /** * Gets the current separator * @return the separator. */ public char getSeparator() { return separator; } }