/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.velocity; import java.util.Stack; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openflexo.logging.FlexoLogger; /** * @author gpolet * */ public class PostVelocityParser { private static final Logger logger = FlexoLogger.getLogger(PostVelocityParser.class.getPackage().getName()); private static final String TAG_END = "end"; private static final String[] TAGS = new String[] { "single", "onereturn", TAG_END }; private static final String TAG_START = "@"; public static String parseAndRenderCustomTag(String s) { try { Stack<String> tags = new Stack<String>(); Stack<String> output = new Stack<String>(); int index = 0, next; String nextTag = findNextTag(s, index); boolean lastMatchWasEndTag = false; if (nextTag == null) { return s; } while (nextTag != null) { next = s.indexOf(TAG_START + nextTag, index); String substring = s.substring(index, next); if (substring.length() > 0) { boolean startsWithTilde = substring.charAt(0) == '~'; boolean endsWithTilde = substring.charAt(substring.length() - 1) == '~'; if (startsWithTilde && endsWithTilde) { substring = substring.substring(1, substring.length() - 1); } else if (endsWithTilde) { substring = substring.substring(0, substring.length() - 1); } else if (startsWithTilde) { substring = substring.substring(1); } } if (lastMatchWasEndTag) { output.push(output.pop() + substring); } else { output.push(substring); } lastMatchWasEndTag = false; if (nextTag.equals(TAG_END)) { int tmp = s.indexOf('\n', next); if (next + nextTag.length() + 1 < s.length() && s.charAt(next + nextTag.length() + 1) == '@' && tmp > -1 && tmp < s.length() - 1) { index = tmp + 1; } else { index = next + nextTag.length() + 1; } lastMatchWasEndTag = true; String tagToRender = tags.pop(); String middleText = output.pop(); output.push(output.pop() + render(tagToRender, middleText)); } else { tags.push(nextTag); index = next + nextTag.length() + 1; int nextNewLine = s.indexOf('\n', index); if (nextNewLine > -1) { if (s.substring(index, nextNewLine).trim().length() == 0) { index = nextNewLine + 1; } } } nextTag = findNextTag(s, index); } if (index < s.length() && s.charAt(index) == '~') { index++; } return output.firstElement() + s.substring(index); } catch (RuntimeException e) { e.printStackTrace(); } return s; } /** * @param tagToRender * @param middleText * @return */ private static String render(String tagToRender, String middleText) { if (tagToRender.equals(TAGS[0])) { return single(middleText); } else if (tagToRender.equals(TAGS[1])) { return onereturn(middleText); } if (logger.isLoggable(Level.WARNING)) { logger.warning("Unknown tag: " + tagToRender); } return null; } /** * @param middleText * @return */ private static String onereturn(String middleText) { StringBuffer sb = new StringBuffer(); Matcher m = Pattern.compile("\\s*?\n\\s*").matcher(middleText); while (m.find()) { m.appendReplacement(sb, "\n"); } m.appendTail(sb); return sb.toString(); } /** * @param middleText * @return */ private static String single(String middleText) { return middleText.replaceAll("\\s+", " "); } /** * @param index * @return */ private static String findNextTag(String input, int index) { int next = input.indexOf(TAG_START, index); while (next > -1) { for (String tag : TAGS) { if (input.regionMatches(next + 1, tag, 0, tag.length())) { return tag; } } next = input.indexOf(TAG_START, next + 1); } return null; } public static void main(String[] args) { String text = " public void appendToResponse(WOResponse r, WOContext c) {\n" + " hiddenFieldValue = null;\n" + " pageDA = getUrlForOperation(context() @single\n" + "@end@\n" + " , getOperationComponentInstanceID());\n" + " \n" + " super.appendToResponse(r,c);\n" + " }\n" + "\n" + ""; System.out.println(parseAndRenderCustomTag(text)); System.out.println(""); String s = "coucou~@onereturn~middle\n\n\n~blabla~@end~"; System.out.println(s); System.out.println("##########################"); System.out.println(parseAndRenderCustomTag(s)); } }