/** * * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved. * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. * * Copyright (c) 2009-2014 Câmara dos Deputados. Todos os direitos reservados. * * e-Democracia é um software livre; você pode redistribuí-lo e/ou modificá-lo dentro * dos termos da Licença Pública Geral Menor GNU como publicada pela Fundação do * Software Livre (FSF); na versão 2.1 da Licença, ou (na sua opinião) qualquer versão. * * Este programa é distribuído na esperança de que possa ser útil, mas SEM NENHUMA GARANTIA; * sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou APLICAÇÃO EM PARTICULAR. * Veja a Licença Pública Geral Menor GNU para maiores detalhes. * */ package com.liferay.portal.parsers.bbcode; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.IntegerWrapper; import com.liferay.portal.kernel.util.SetUtil; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.Stack; /** * @author Iliyan Peychev */ public class BBCodeParser { public static final int TYPE_DATA = 0x04; public static final int TYPE_TAG_END = 0x02; public static final int TYPE_TAG_START = 0x01; public static final int TYPE_TAG_START_END = TYPE_TAG_START | TYPE_TAG_END; public BBCodeParser() { _blockElements = SetUtil.fromArray( new String[] { "*", "center", "code", "justify", "left", "li", "list", "q", "quote", "right", "table", "td", "th", "tr" }); _inlineElements = SetUtil.fromArray( new String[] { "b", "color", "font", "i", "img", "s", "size", "u", "url", "youtube" }); _selfCloseElements = SetUtil.fromArray(new String[] {"*"}); } public List<BBCodeItem> parse(String text) { List<BBCodeItem> bbCodeItems = new ArrayList<BBCodeItem>(); BBCodeLexer bbCodeLexer = new BBCodeLexer(text); Stack<String> tags = new Stack<String>(); IntegerWrapper marker = new IntegerWrapper(); BBCodeToken bbCodeToken = null; while ((bbCodeToken = bbCodeLexer.getNextBBCodeToken()) != null) { handleData(bbCodeItems, bbCodeLexer, marker, bbCodeToken, text); if (bbCodeToken.getStartTag() == null) { handleTagEnd(bbCodeItems, tags, bbCodeToken); continue; } handleTagStart(bbCodeItems, tags, bbCodeToken); String startTag = bbCodeToken.getStartTag(); if (!startTag.equals("code")) { continue; } while (true) { bbCodeToken = bbCodeLexer.getNextBBCodeToken(); if (bbCodeToken == null) { break; } String endTag = GetterUtil.getString(bbCodeToken.getEndTag()); if (endTag.equals("code")) { break; } } handleData(bbCodeItems, bbCodeLexer, marker, bbCodeToken, text); if (bbCodeToken != null) { handleTagEnd(bbCodeItems, tags, bbCodeToken); } else { break; } } handleData(bbCodeItems, bbCodeLexer, marker, null, text); handleTagEnd(bbCodeItems, tags, null); return bbCodeItems; } protected void handleData( List<BBCodeItem> bbCodeItems, BBCodeLexer bbCodeLexer, IntegerWrapper marker, BBCodeToken bbCodeToken, String data) { int length = data.length(); int lastIndex = length; if (bbCodeToken != null) { length = bbCodeToken.getStart(); lastIndex = bbCodeLexer.getLastIndex(); } if (length > marker.getValue()) { BBCodeItem bbCodeItem = new BBCodeItem( TYPE_DATA, null, data.substring(marker.getValue(), length)); bbCodeItems.add(bbCodeItem); } marker.setValue(lastIndex); } protected void handleTagEnd( List<BBCodeItem> bbCodeItems, Stack<String> tags, BBCodeToken bbCodeToken) { int size = 0; if (bbCodeToken != null) { String endTag = bbCodeToken.getEndTag(); for (size = tags.size() - 1; size >= 0; size--) { if (endTag.equals(tags.elementAt(size))) { break; } } } if (size >= 0) { for (int i = tags.size() - 1; i >= size; i--) { BBCodeItem bbCodeItem = new BBCodeItem( TYPE_TAG_END, null, tags.elementAt(i)); bbCodeItems.add(bbCodeItem); } tags.setSize(size); } } protected void handleTagStart( List<BBCodeItem> bbCodeItems, Stack<String> tags, BBCodeToken bbCodeToken) { String startTag = bbCodeToken.getStartTag(); if (_blockElements.contains(startTag)) { String currentTag = null; while (!tags.isEmpty() && ((currentTag = tags.lastElement()) != null) && _inlineElements.contains(currentTag)) { BBCodeToken currentTagBBCodeToken = new BBCodeToken(currentTag); handleTagEnd(bbCodeItems, tags, currentTagBBCodeToken); } } if (_selfCloseElements.contains(startTag) && !tags.isEmpty() && startTag.equals(tags.lastElement())) { BBCodeToken tagBBCodeToken = new BBCodeToken(startTag); handleTagEnd(bbCodeItems, tags, tagBBCodeToken); } tags.push(startTag); BBCodeItem bbCodeItem = new BBCodeItem( TYPE_TAG_START, bbCodeToken.getAttribute(), startTag); bbCodeItems.add(bbCodeItem); } private Set<String> _blockElements; private Set<String> _inlineElements; private Set<String> _selfCloseElements; }