Java tutorial
/*! * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * * Copyright (c) 2002-2018 Hitachi Vantara. All rights reserved. * */ package org.pentaho.platform.util.xml; import org.dom4j.Node; import org.pentaho.platform.api.engine.IDocumentResourceLoader; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.util.messages.LocaleHelper; import javax.xml.transform.TransformerException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class XForm { // TODO sbarkdull, make this an enumerated type public static final int TYPE_RADIO = 1; public static final int TYPE_SELECT = 2; public static final int TYPE_LIST = 3; public static final int TYPE_LIST_MULTI = 4; public static final int TYPE_CHECK_MULTI = 5; public static final int TYPE_CHECK_MULTI_SCROLL = 6; public static final int TYPE_CHECK_MULTI_SCROLL_2_COLUMN = 7; public static final int TYPE_CHECK_MULTI_SCROLL_3_COLUMN = 8; public static final int TYPE_CHECK_MULTI_SCROLL_4_COLUMN = 9; public static final int TYPE_TEXT = 10; // TODO sbarkdull make this an enumerated type public static final int OUTPUT_XFORM = 1; public static final int OUTPUT_HTML = 2; public static final int OUTPUT_HTML_PAGE = 3; public static String transformSnippet(final Node xForm, final IPentahoSession session, final IDocumentResourceLoader loader) throws TransformerException { return XForm.transformSnippet(xForm.asXML(), null, session, loader); } /** * Using html4.xsl, wrap the XForm String in xFormSnippet in a <pho:snippet>, and transform the wrapped XSL * into an HTML form snippet. * * @param xFormSnippet * The xml snippet being transformed. * @param method * HTML form method, generally either "post" or "get". * @param session * @return HTML form snippet, null on error. * @throws TransformerException * if the transform fails. */ public static String transformSnippet(final String xFormSnippet, final String method, final IPentahoSession session, final IDocumentResourceLoader loader) throws TransformerException { StringBuffer xForm = null; xForm = new StringBuffer() .append("<?xml version=\"1.0\" encoding=\"" + LocaleHelper.getSystemEncoding() + "\" ?>") //$NON-NLS-1$ //$NON-NLS-2$ .append("<pho:snippet xmlns:xf=\"http://www.w3.org/2002/xforms\" xmlns:pho=\"http://www.w3.org/1999/homl\">") //$NON-NLS-1$ .append(xFormSnippet).append("</pho:snippet>"); //$NON-NLS-1$ String html = XForm.transform(xForm.toString(), method, session, loader); // This is required so that we don't get a new form for each control // TODO fix the transform so that this code is not required... int pos1 = html.indexOf("<form name=\"pentaho-form\""); //$NON-NLS-1$ int pos2 = html.indexOf("enctype=\"application/x-www-form-urlencoded\">", pos1); //$NON-NLS-1$ if (pos2 > 0) { html = html.substring(pos2 + 44); pos2 = html.indexOf("</form>"); //$NON-NLS-1$ if (pos2 > 0) { html = html.substring(0, pos2); } } return html; } /** * Using html4.xsl, transform the xml in the xForm string to an HTML form snippet. * * @param xForm * The xml string being transformed. * @param method * HTML form method, generally either "post" or "get". * @param session * @return HTML form snippet, null on error. * @throws TransformerException * if the transform fails. */ public static String transform(final String xForm, final String method, final IPentahoSession session, final IDocumentResourceLoader loader) throws TransformerException { HashMap<String, String> parameters = new HashMap<String, String>(); if (method != null) { parameters.put("form-method", method); //$NON-NLS-1$ } else { parameters.put("form-method", "GET"); //$NON-NLS-1$ //$NON-NLS-2$ } // TODO: Why isn't the parameters map above being passed in as the 4th parameter? return XmlHelper.transformXml("html4.xsl", null, xForm, null, loader).toString(); //$NON-NLS-1$ } public static void createXFormHeader(final String formName, final StringBuffer xformHeader) { xformHeader.append("<head>") //$NON-NLS-1$ .append("<link rel=\"stylesheet\" type=\"text/css\" href=\"/pentaho-style/active/default.css\" />") //$NON-NLS-1$ .append("<xf:model id=\"").append(formName).append("\">") //$NON-NLS-1$ //$NON-NLS-2$ .append("<xf:instance>"); //$NON-NLS-1$ } public static void completeXFormHeader(final String formName, final StringBuffer xformHeader) { xformHeader.append("</xf:instance>") //$NON-NLS-1$ .append("<xf:submission action=\"\" separator=\"&\" method=\"urlencoded-get\" id=\"") //$NON-NLS-1$ .append(formName).append("\" />") //$NON-NLS-1$ .append("</xf:model>") //$NON-NLS-1$ .append("</head>"); //$NON-NLS-1$ } public static void createXFormSubmit(final String formName, final StringBuffer xformBody, final String buttonText) { xformBody.append("<xf:submit id=\"").append(formName).append("\" submission=\"").append(formName) //$NON-NLS-1$//$NON-NLS-2$ .append("\">") //$NON-NLS-1$ .append("<xf:label>").append(buttonText).append("</xf:label>") //$NON-NLS-1$ //$NON-NLS-2$ .append("</xf:submit>"); //$NON-NLS-1$ } public static String completeXForm(final int outputType, final String formName, final StringBuffer xformHeader, final StringBuffer xformBody, final IPentahoSession session, final IDocumentResourceLoader loader) throws TransformerException { xformHeader.append("</xf:instance>") //$NON-NLS-1$ .append("<xf:submission action=\"\" separator=\"&\" method=\"urlencoded-get\" id=\"") //$NON-NLS-1$ .append(formName).append("\" />") //$NON-NLS-1$ .append("</xf:model>") //$NON-NLS-1$ .append("</head>"); //$NON-NLS-1$ if (outputType == XForm.OUTPUT_XFORM) { xformHeader.append(xformBody); return xformHeader.toString(); } else if (outputType == XForm.OUTPUT_HTML) { xformHeader.append("<body dir=\"").append(LocaleHelper.getTextDirection()).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$ xformHeader.append(xformBody); xformHeader.append("</body>"); //$NON-NLS-1$ return XForm.transformSnippet(xformHeader.toString(), "GET", session, loader); //$NON-NLS-1$ } else if (outputType == XForm.OUTPUT_HTML_PAGE) { StringBuffer xForm = new StringBuffer(); xForm.append( "<html xmlns=\"http://www.w3.org/2002/06/xhtml2\" xmlns:xf=\"http://www.w3.org/2002/xforms\" xmlns:pho=\"http://www.w3.org/2002/xhoml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"); //$NON-NLS-1$ if (xformBody.indexOf("{xform-header}") > -1) { //$NON-NLS-1$ String header = xformHeader.toString(); header = header.replaceFirst("<head>", ""); //$NON-NLS-1$ //$NON-NLS-2$ header = header.replaceFirst("</head>", ""); //$NON-NLS-1$ //$NON-NLS-2$ String tmp = xformBody.toString(); tmp = tmp.replaceFirst("\\{xform-header\\}", header); //$NON-NLS-1$ String html = XForm.transform(tmp, "GET", session, loader); //$NON-NLS-1$ return html; } else { xForm.append(xformHeader); xForm.append(xformBody); xForm.append("</html>"); //$NON-NLS-1$ String html = XForm.transform(xForm.toString(), "GET", session, loader); //$NON-NLS-1$ return "<html><body dir=\"" + LocaleHelper.getTextDirection() + "\">" + html + "</body></html>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } else { return null; } } public static void createXFormControl(final String fieldName, final Object defaultValues, final String formName, final StringBuffer xformHeader, final StringBuffer xformBody, final boolean visible) { // create some xform to represent this parameter... if (xformHeader.length() == 0) { // this is the first parameter, need to create the header... XForm.createXFormHeader(formName, xformHeader); } XForm.setDefaultValues(fieldName, defaultValues, xformHeader); if (visible) { xformBody.append("<xf:input model=\"").append(formName).append("\" id=\"").append(fieldName) //$NON-NLS-1$//$NON-NLS-2$ .append("\" ref=\"").append(fieldName).append("\"></xf:input>"); //$NON-NLS-1$ //$NON-NLS-2$ } } private static void setDefaultValues(final String fieldName, final Object defaultValues, final StringBuffer xformHeader) { xformHeader.append("<data xmlns=\"\">"); //$NON-NLS-1$ if (defaultValues instanceof String) { xformHeader.append("<").append(fieldName).append(">").append(XmlHelper.encode((String) defaultValues)) //$NON-NLS-1$//$NON-NLS-2$ .append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ } else if (defaultValues instanceof String[]) { String[] values = (String[]) defaultValues; for (String element : values) { xformHeader.append("<").append(fieldName).append(">").append(XmlHelper.encode(element)).append("</") //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ .append(fieldName).append(">"); //$NON-NLS-1$ } } else if (defaultValues instanceof Object[]) { Object[] values = (String[]) defaultValues; for (Object element : values) { xformHeader.append("<").append(fieldName).append(">").append(XmlHelper.encode(element.toString())) //$NON-NLS-1$//$NON-NLS-2$ .append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ } } else if (defaultValues == null) { xformHeader.append("<").append(fieldName).append("></").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else { xformHeader.append("<").append(fieldName).append(">").append(XmlHelper.encode(defaultValues.toString())) //$NON-NLS-1$//$NON-NLS-2$ .append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ } xformHeader.append("</data>"); //$NON-NLS-1$ } public static void createXFormControl(final int type, final String fieldName, Object defaultValues, final List values, final Map displayNames, final String formName, final StringBuffer xformHeader, final StringBuffer xformBody) { // If displaying a text box value might be null and we still want to display the text box if ((type != XForm.TYPE_TEXT) && (values == null)) { return; } // create some xform to represent this parameter... if (xformHeader.length() == 0) { // this is the first parameter, need to create the header... XForm.createXFormHeader(formName, xformHeader); } // If the values is not null and if there is only one item in the list make it the default if ((values != null) && (values.size() == 1)) { defaultValues = XmlHelper.encode(values.get(0).toString()); } XForm.setDefaultValues(fieldName, defaultValues, xformHeader); String appearance = ""; //$NON-NLS-1$ if (type == XForm.TYPE_TEXT) { xformBody.append("<xf:input model=\"").append(formName).append("\" id=\"").append(fieldName) //$NON-NLS-1$//$NON-NLS-2$ .append("\" ref=\"").append(fieldName).append("\"></xf:input>"); //$NON-NLS-1$ //$NON-NLS-2$ } else if ((type == XForm.TYPE_RADIO) || (type == XForm.TYPE_SELECT) || (type == XForm.TYPE_LIST)) { switch (type) { case TYPE_RADIO: appearance = "appearance=\"full\""; break; //$NON-NLS-1$ case TYPE_SELECT: appearance = ""; break; //$NON-NLS-1$ case TYPE_LIST: appearance = "appearance=\"compact\""; break; //$NON-NLS-1$ } xformBody.append("<xf:select1 ").append(appearance).append(" model=\"").append(formName) //$NON-NLS-1$//$NON-NLS-2$ .append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (values != null) { Iterator listIterator = values.iterator(); while (listIterator.hasNext()) { String value = XmlHelper.encode(listIterator.next().toString()); String displayValue = (displayNames != null) ? XmlHelper.encode((String) displayNames.get(value)) : value; if (displayValue == null) { displayValue = value; } xformBody.append("<xf:item><xf:label>").append(displayValue).append("</xf:label><xf:value>") //$NON-NLS-1$//$NON-NLS-2$ .append(value).append("</xf:value></xf:item>"); //$NON-NLS-1$ } } xformBody.append("</xf:select1>"); //$NON-NLS-1$ } else if ((type == XForm.TYPE_LIST_MULTI) || (type == XForm.TYPE_CHECK_MULTI) || (type == XForm.TYPE_CHECK_MULTI_SCROLL) || (type == XForm.TYPE_CHECK_MULTI_SCROLL_2_COLUMN) || (type == XForm.TYPE_CHECK_MULTI_SCROLL_3_COLUMN) || (type == XForm.TYPE_CHECK_MULTI_SCROLL_4_COLUMN)) { switch (type) { case TYPE_CHECK_MULTI: appearance = "appearance=\"full\""; break; //$NON-NLS-1$ case TYPE_LIST_MULTI: appearance = "appearance=\"compact\""; break; //$NON-NLS-1$ case TYPE_CHECK_MULTI_SCROLL: appearance = "appearance=\"full-scroll\" columns=\"1\""; break; //$NON-NLS-1$ case TYPE_CHECK_MULTI_SCROLL_2_COLUMN: appearance = "appearance=\"full-scroll\" columns=\"2\""; break; //$NON-NLS-1$ case TYPE_CHECK_MULTI_SCROLL_3_COLUMN: appearance = "appearance=\"full-scroll\" columns=\"3\""; break; //$NON-NLS-1$ case TYPE_CHECK_MULTI_SCROLL_4_COLUMN: appearance = "appearance=\"full-scroll\" columns=\"4\""; break; //$NON-NLS-1$ } xformBody.append("<xf:select ").append(appearance).append(" model=\"").append(formName) //$NON-NLS-1$//$NON-NLS-2$ .append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (values != null) { Iterator listIterator = values.iterator(); while (listIterator.hasNext()) { String value = XmlHelper.encode(listIterator.next().toString()); String displayValue = (displayNames != null) ? XmlHelper.encode((String) displayNames.get(value)) : value; if (displayValue == null) { displayValue = value; } xformBody.append("<xf:item><xf:label>").append(displayValue).append("</xf:label><xf:value>") //$NON-NLS-1$//$NON-NLS-2$ .append(value).append("</xf:value></xf:item>"); //$NON-NLS-1$ } } xformBody.append("</xf:select>"); //$NON-NLS-1$ } } }