/******************************************************************************* * Copyright (c) 2007 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.vpe.jsf.template; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; import org.jboss.tools.vpe.editor.context.VpePageContext; import org.jboss.tools.vpe.editor.template.VpeCreationData; import org.jboss.tools.vpe.editor.util.HTML; import org.mozilla.interfaces.nsIDOMDocument; import org.mozilla.interfaces.nsIDOMElement; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Sergey Dzmitrovich * * template for <h:outputFormat .../> jsf tag * */ public class JsfOutputFormatTemplate extends AbstractOutputJsfTemplate { /** * name of "choice" */ private static final String CHOICE_NAME = "choice"; //$NON-NLS-1$ /** * message format elements separator */ private static final String MESSAGE_FORMAT_ELEMENTS_SEPARATOR = ","; //$NON-NLS-1$ /** * choices separator */ private static final String CHOICES_SEPARATOR = "\\|"; //$NON-NLS-1$ /** * choices separator */ private static final String CHOICE_PAIR_SEPARATOR = "#"; //$NON-NLS-1$ /** * message format elements pattern */ private static final String MESSAGE_FORMAT_ELEMENTS_PATTERN = "\\{(\\d+)(,.*?){0,2}?\\}"; //$NON-NLS-1$ /* * (non-Javadoc) * * @see org.jboss.tools.vpe.editor.template.VpeTemplate#create(org.jboss.tools.vpe.editor.context.VpePageContext, * org.w3c.dom.Node, org.mozilla.interfaces.nsIDOMDocument) */ public VpeCreationData create(VpePageContext pageContext, Node sourceNode, nsIDOMDocument visualDocument) { Element element = (Element) sourceNode; // create span element nsIDOMElement span = visualDocument.createElement(HTML.TAG_SPAN); // creation data VpeCreationData creationData = new VpeCreationData(span); // copy attributes copyOutputJsfAttributes(span, element); processOutputAttribute(pageContext, visualDocument, element, span, creationData); return creationData; } @Override public boolean recreateAtAttrChange(VpePageContext pageContext, Element sourceElement, nsIDOMDocument visualDocument, nsIDOMElement visualNode, Object data, String name, String value) { return true; } @Override protected String prepareAttrValue(VpePageContext pageContext, Element parent, Attr attr) { return prepareAttrValueByParams(attr.getNodeValue(), getParams(parent)); } /** * find message format elements and update value * * @param nodeValue * @param paramList * @return */ private String prepareAttrValueByParams(String nodeValue, List<Element> paramList) { // matcher Matcher matcher = Pattern.compile(MESSAGE_FORMAT_ELEMENTS_PATTERN).matcher(nodeValue); int lastPos = 0; StringBuilder sb = new StringBuilder(); while (matcher.find()) { // get next message format elements String messageFormatElement = matcher.group(); // set end and start int start = matcher.start(); int end = matcher.end(); // get value of message format element String value = parseMessageFormatElement(messageFormatElement, paramList); // update value sb.append(nodeValue.substring(lastPos, start)); sb.append(value); lastPos = end; } sb.append(nodeValue.substring(lastPos)); return sb.toString(); } /** * get value of message format element * * @param messageFormatElement * @param paramList * @return */ private String parseMessageFormatElement(String messageFormatElement, List<Element> paramList) { String value = null; // separate message format element String[] parametres = messageFormatElement .split(MESSAGE_FORMAT_ELEMENTS_SEPARATOR); // if this is "choice" format if (parametres.length > 2) { String format = parametres[1].trim(); if (CHOICE_NAME.equalsIgnoreCase(format)) { // get "choice" as value String choice = getChoice(parametres[2]); if (choice != null) value = choice.replaceAll("[\\{\\}]", ""); //$NON-NLS-1$//$NON-NLS-2$ } } // if this is not "choice" format if (value == null) { // get number of param String paramNumber = parametres[0].trim(); paramNumber = paramNumber.replaceAll("[\\{\\}]", ""); //$NON-NLS-1$//$NON-NLS-2$ try { // decode int num = Integer.decode(paramNumber); if (num < paramList.size() && paramList.get(num).hasAttribute(JSF.ATTR_VALUE)) { // get param's value Element paramElement = paramList.get(num); value = paramElement.hasAttribute(JSF.ATTR_VALUE) ? paramElement.getAttribute(JSF.ATTR_VALUE) : null; } } catch (NumberFormatException e) { // illegal param value } } // return or value or starting value return value != null ? value : messageFormatElement; } /** * get choice * * @param choiceString * @return */ private String getChoice(String choiceString) { // separate all choices String[] choices = choiceString.split(CHOICES_SEPARATOR); // separate first choice pair(choice value / choice string) String[] choice = choices[0].split(CHOICE_PAIR_SEPARATOR); // return choice string if (choice.length > 1) { return choice[1]; } return null; } /** * get all <f:param .../> tags * * @param sourcElement * @return */ private List<Element> getParams(Element sourcElement) { NodeList nodeList = sourcElement.getChildNodes(); List<Element> params = new ArrayList<Element>(); for (int i = 0; i < nodeList.getLength(); i++) { Node child = nodeList.item(i); if (JSF.TAG_PARAM.equals(child.getLocalName())) { params.add((Element) child); } } return params; } }