/**
* Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors
* (see CONTRIBUTORS.md)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. A copy of the
* License is distributed with this work in the LICENSE.md file. You may
* also obtain a copy of the License from
*
* 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 org.gennai.gungnir.topology.processor;
import static org.gennai.gungnir.GungnirConst.*;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.gennai.gungnir.tuple.FieldAccessor;
import com.google.common.collect.Lists;
public final class ProcessorUtils {
private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\@");
private static final Pattern FIELD_PATTERN = Pattern.compile("@(\\w+(\\.\\w+)*)!?");
private ProcessorUtils() {
}
public static final class PlaceHolder implements Serializable {
private static final long serialVersionUID = SERIAL_VERSION_UID;
private FieldAccessor field;
private int start;
private int end;
private PlaceHolder(FieldAccessor field, int start, int end) {
this.field = field;
this.start = start;
this.end = end;
}
public FieldAccessor getField() {
return field;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
}
public static final class PlaceHolders implements Serializable, Iterable<PlaceHolder> {
private static final long serialVersionUID = SERIAL_VERSION_UID;
private String src;
private List<PlaceHolder> placeHolders = Lists.newArrayList();
private PlaceHolders(String src) {
this.src = src;
}
public String getSrc() {
return src;
}
private void add(FieldAccessor field, int start, int end) {
placeHolders.add(new PlaceHolder(field, start, end));
}
@Override
public Iterator<PlaceHolder> iterator() {
return placeHolders.iterator();
}
public boolean isEmpty() {
if (placeHolders == null) {
return true;
}
return placeHolders.isEmpty();
}
public int size() {
return placeHolders.size();
}
@Override
public String toString() {
return src;
}
}
public static PlaceHolders findPlaceHolders(String src) {
StringBuilder sb = new StringBuilder();
int start = 0;
List<Integer> escapes = Lists.newArrayList();
Matcher matcher = ESCAPE_PATTERN.matcher(src);
while (matcher.find()) {
escapes.add(matcher.start() - escapes.size());
sb.append(src.substring(start, matcher.start()));
sb.append('@');
start = matcher.end();
}
sb.append(src.substring(start));
src = sb.toString();
PlaceHolders placeHolders = new PlaceHolders(src);
matcher = FIELD_PATTERN.matcher(src);
while (matcher.find()) {
if (!escapes.contains(matcher.start())) {
String fieldName = matcher.group(1);
String[] names = fieldName.split("\\.");
FieldAccessor field = null;
for (String name : names) {
if (field == null) {
field = new FieldAccessor(name);
} else {
field = new FieldAccessor(name, field);
}
}
placeHolders.add(field, matcher.start(), matcher.end());
}
}
return placeHolders;
}
}