List of usage examples for java.lang StringBuffer subSequence
@Override public synchronized CharSequence subSequence(int start, int end)
From source file:com.edgenius.wiki.render.filter.MacroFilter.java
/** *//*from w w w. jav a 2s. c o m*/ private void checkGroup(final int initPos, CharSequence input, final LinkedList<GroupProcessor> stack, List<GroupProcessor> processors) { final List<Region> pairRegions = new ArrayList<Region>(); singleMacroProvider.replaceByTokenVisitor(input, new TokenVisitor<Matcher>() { public void handleMatch(StringBuffer buffer, Matcher result) { String macroName = result.group(1); if (macroName != null && !macroName.startsWith("$")) { Macro macro = macroMgr.getMacro(macroName); if (macro != null) { //IMPORTANT: here does not check Macro.isPair() and also put it into pairRegions for following process //it is the sequence of process must keep consistant with physical sequence in input text, //for example, {table}{cell}...{rowdiv}, rowdiv is single and must be after cell int start = result.start(0); int end = result.end(0); Region pair = new Region(start, end); //no parameter, then mark as unknown, otherwise, must be a start macro if (StringUtils.isBlank(result.group(2))) { pair.setKey(MACRO_REGION_KEY_UNKNOWN); } else { pair.setKey(MACRO_REGION_KEY_START); } //just for temporary to remember the macro name... pair.setContent(macroName); //sum to list pairRegions.add(pair); } } } }); int size = pairRegions.size(); if (size > 0) { StringBuffer inputBuf = new StringBuffer(input); for (int idx = 0; idx < size; idx++) { Region reg = pairRegions.get(idx); Macro macro = macroMgr.getMacro(reg.getContent()); if (macro.isPaired()) { int deep = 0; Region pair = null; //looking for pairs... for (int chIdx = idx + 1; chIdx < size; chIdx++) { Region next = pairRegions.get(chIdx); if (StringUtils.equalsIgnoreCase(reg.getContent(), next.getContent())) { //start is unknown (no attribute), then end must be unknown if (MACRO_REGION_KEY_UNKNOWN.equals(reg.getKey()) && MACRO_REGION_KEY_UNKNOWN.equals(next.getKey())) { //matched pair = next; //skip all internal node - which is handle by embedded recursive idx = chIdx; break; } if (MACRO_REGION_KEY_START.equals(reg.getKey()) && MACRO_REGION_KEY_UNKNOWN.equals(next.getKey())) { if (deep == 0) { //matched; pair = next; //skip all internal node - which is handle by embedded recursive idx = chIdx; break; } else { //just another inner same name macro matched, deep minus 1 deep--; } } if (MACRO_REGION_KEY_START.equals(next.getKey())) { //ok, it gets another start, in 4th scenarios - then add deep deep++; } } } //ok, success find paired if (pair != null) { int start = initPos + reg.getStart(); int end = initPos + pair.getEnd(); int contentStart = initPos + reg.getEnd(); int contentEnd = initPos + pair.getStart(); GroupProcessor currProcessor = stack.size() == 0 ? null : stack.getLast(); if (currProcessor != null) { currProcessor.adoptChild(macro, start, end); } if (macro.isProcessEmbedded() && (end > start)) { if (macro.hasChildren() != null) { stack.add(((GroupProcessorMacro) macro).newGroupProcessor(macro, start, end)); } checkGroup(contentStart, inputBuf.subSequence(contentStart - initPos, contentEnd - initPos), stack, processors); if (macro.hasChildren() != null) { //pop the current one, means it is a completed GroupProcessor processors.add(stack.removeLast()); } } } } else { //single macro - directly detect if it is child GroupProcessor currProcessor = stack.size() == 0 ? null : stack.getLast(); if (currProcessor != null) { currProcessor.adoptChild(macro, initPos + reg.getStart(), initPos + reg.getEnd()); } } } } }