001/** 002 * Copyright (C) 2006-2020 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.server.lang; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.NoSuchElementException; 021 022public class StringPropertiesTokenizer { 023 024 private String input; 025 026 private char[] delim; 027 028 private int pos = 0; 029 030 private char lastDelimiter = 0; 031 032 private boolean isDelimiter = false; 033 034 public StringPropertiesTokenizer(final String str) { 035 input = str; 036 delim = ", \t\r\n\f".toCharArray(); 037 } 038 039 public Collection<String> tokens() { 040 final Collection<String> out = new ArrayList<>(); 041 while (hasMoreTokens()) { 042 out.add(nextToken()); 043 } 044 return out; 045 } 046 047 private boolean hasMoreTokens() { 048 final int oldpos = pos; 049 final char olddelim = lastDelimiter; 050 try { 051 nextToken(); 052 return true; 053 } catch (final NoSuchElementException nsee) { 054 return false; 055 } finally { 056 pos = oldpos; 057 lastDelimiter = olddelim; 058 } 059 } 060 061 private String nextToken() { 062 if (pos >= input.length()) { 063 throw new NoSuchElementException(); 064 } 065 066 final StringBuilder sb = new StringBuilder(); 067 char prevch = 0; 068 char ch; 069 while (pos < input.length()) { 070 lastDelimiter = ch = input.charAt(pos); 071 if (isDelimiter(ch, prevch)) { 072 break; 073 } 074 if (isDelimiter(ch, (char) 0) && prevch == '\\') { 075 sb.setLength(sb.length() - 1); 076 } 077 078 sb.append(ch); 079 prevch = ch; 080 pos++; 081 } 082 isDelimiter = false; 083 if (sb.length() == 0) { 084 pos++; 085 return nextToken(); 086 } 087 088 return sb.toString(); 089 } 090 091 public String nextToken(final String delim) { 092 this.delim = delim.toCharArray(); 093 return nextToken(); 094 } 095 096 public boolean isDelimiter() { 097 return isDelimiter; 098 } 099 100 private boolean isDelimiter(final char ch, final char prevch) { 101 for (char currentChar : delim) { 102 if (ch == currentChar && prevch != '\\') { 103 return true; 104 } 105 } 106 return false; 107 } 108}