001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * @created Mar 22, 2005
014: * @author James Dixon
015: *
016: */
017: package org.pentaho.core.util;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023:
024: import javax.xml.transform.TransformerException;
025:
026: import org.dom4j.Node;
027: import org.pentaho.core.session.IPentahoSession;
028: import org.pentaho.messages.util.LocaleHelper;
029:
030: public class XForm {
031:
032: // TODO sbarkdull, make this an enumerated type
033: public static final int TYPE_RADIO = 1;
034:
035: public static final int TYPE_SELECT = 2;
036:
037: public static final int TYPE_LIST = 3;
038:
039: public static final int TYPE_LIST_MULTI = 4;
040:
041: public static final int TYPE_CHECK_MULTI = 5;
042:
043: public static final int TYPE_CHECK_MULTI_SCROLL = 6;
044:
045: public static final int TYPE_CHECK_MULTI_SCROLL_2_COLUMN = 7;
046:
047: public static final int TYPE_CHECK_MULTI_SCROLL_3_COLUMN = 8;
048:
049: public static final int TYPE_CHECK_MULTI_SCROLL_4_COLUMN = 9;
050:
051: public static final int TYPE_TEXT = 10;
052:
053: // TODO sbarkdull make this an enumerated type
054: public static final int OUTPUT_XFORM = 1;
055:
056: public static final int OUTPUT_HTML = 2;
057:
058: public static final int OUTPUT_HTML_PAGE = 3;
059:
060: public static String transformSnippet(Node xForm,
061: IPentahoSession session) throws TransformerException {
062:
063: return transformSnippet(xForm.asXML(), null, session);
064:
065: }
066:
067: /**
068: * Using html4.xsl, wrap the XForm String in xFormSnippet in a <pho:snippet>, and
069: * transform the wrapped XSL into an HTML form snippet.
070: *
071: * @param xFormSnippet The xml snippet being transformed.
072: * @param method HTML form method, generally either "post" or "get".
073: * @param session
074: * @return HTML form snippet, null on error.
075: * @throws TransformerException if the transform fails.
076: */
077: public static String transformSnippet(String xFormSnippet,
078: String method, IPentahoSession session)
079: throws TransformerException {
080:
081: StringBuffer xForm = null;
082:
083: xForm = new StringBuffer()
084: .append(
085: "<?xml version=\"1.0\" encoding=\"" + LocaleHelper.getSystemEncoding() + "\" ?>") //$NON-NLS-1$ //$NON-NLS-2$
086: .append(
087: "<pho:snippet xmlns:xf=\"http://www.w3.org/2002/xforms\" xmlns:pho=\"http://www.w3.org/1999/homl\">") //$NON-NLS-1$
088: .append(xFormSnippet).append("</pho:snippet>"); //$NON-NLS-1$
089:
090: String html = transform(xForm.toString(), method, session);
091:
092: // This is required so that we don't get a new form for each control
093: // TODO fix the transform so that this code is not required...
094: int pos1 = html.indexOf("<form name=\"pentaho-form\""); //$NON-NLS-1$
095: int pos2 = html.indexOf(
096: "enctype=\"application/x-www-form-urlencoded\">", pos1); //$NON-NLS-1$
097: if (pos2 > 0) {
098: html = html.substring(pos2 + 44);
099: pos2 = html.indexOf("</form>"); //$NON-NLS-1$
100: if (pos2 > 0) {
101: html = html.substring(0, pos2);
102: }
103: }
104:
105: return html;
106: }
107:
108: /**
109: * Using html4.xsl, transform the xml in the xForm string to an HTML form snippet.
110: *
111: * @param xForm The xml string being transformed.
112: * @param method HTML form method, generally either "post" or "get".
113: * @param session
114: * @return HTML form snippet, null on error.
115: * @throws TransformerException if the transform fails.
116: */
117: public static String transform(String xForm, String method,
118: IPentahoSession session) throws TransformerException {
119:
120: HashMap parameters = new HashMap();
121: if (method != null) {
122: parameters.put("form-method", method); //$NON-NLS-1$
123: } else {
124: parameters.put("form-method", "GET"); //$NON-NLS-1$ //$NON-NLS-2$
125: }
126: // TODO: Why isn't the parameters map above being passed in as the 4th parameter?
127: return XmlHelper.transformXml(
128: "html4.xsl", null, xForm, null, session).toString(); //$NON-NLS-1$
129: }
130:
131: public static void createXFormHeader(String formName,
132: StringBuffer xformHeader) {
133:
134: xformHeader
135: .append("<head>") //$NON-NLS-1$
136: .append(
137: "<link rel=\"stylesheet\" type=\"text/css\" href=\"/pentaho-style/active/default.css\" />") //$NON-NLS-1$
138: .append("<xf:model id=\"").append(formName).append("\">") //$NON-NLS-1$ //$NON-NLS-2$
139: .append("<xf:instance>"); //$NON-NLS-1$
140:
141: }
142:
143: public static void completeXFormHeader(String formName,
144: StringBuffer xformHeader) {
145:
146: xformHeader
147: .append("</xf:instance>") //$NON-NLS-1$
148: .append(
149: "<xf:submission action=\"\" separator=\"&\" method=\"urlencoded-get\" id=\"").append(formName).append("\" />") //$NON-NLS-1$ //$NON-NLS-2$
150: .append("</xf:model>") //$NON-NLS-1$
151: .append("</head>"); //$NON-NLS-1$
152:
153: }
154:
155: public static void createXFormSubmit(String formName,
156: StringBuffer xformBody, String buttonText) {
157:
158: xformBody
159: .append("<xf:submit id=\"").append(formName).append("\" submission=\"").append(formName).append("\">") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
160: .append("<xf:label>").append(buttonText).append("</xf:label>") //$NON-NLS-1$ //$NON-NLS-2$
161: .append("</xf:submit>"); //$NON-NLS-1$
162:
163: }
164:
165: public static String completeXForm(int outputType, String formName,
166: StringBuffer xformHeader, StringBuffer xformBody,
167: IPentahoSession session) throws TransformerException {
168: xformHeader
169: .append("</xf:instance>") //$NON-NLS-1$
170: .append(
171: "<xf:submission action=\"\" separator=\"&\" method=\"urlencoded-get\" id=\"").append(formName).append("\" />") //$NON-NLS-1$ //$NON-NLS-2$
172: .append("</xf:model>") //$NON-NLS-1$
173: .append("</head>"); //$NON-NLS-1$
174:
175: if (outputType == OUTPUT_XFORM) {
176: xformHeader.append(xformBody);
177: return xformHeader.toString();
178: } else if (outputType == OUTPUT_HTML) {
179: xformHeader
180: .append("<body dir=\"").append(LocaleHelper.getTextDirection()).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$
181: xformHeader.append(xformBody);
182: xformHeader.append("</body>"); //$NON-NLS-1$
183: return transformSnippet(xformHeader.toString(),
184: "GET", session); //$NON-NLS-1$
185: } else if (outputType == OUTPUT_HTML_PAGE) {
186: StringBuffer xForm = new StringBuffer();
187: xForm
188: .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$
189: if (xformBody.indexOf("{xform-header}") > -1) { //$NON-NLS-1$
190: String header = xformHeader.toString();
191: header = header.replaceFirst("<head>", ""); //$NON-NLS-1$ //$NON-NLS-2$
192: header = header.replaceFirst("</head>", ""); //$NON-NLS-1$ //$NON-NLS-2$
193: String tmp = xformBody.toString();
194: tmp = tmp.replaceFirst("\\{xform-header\\}", header); //$NON-NLS-1$
195: String html = transform(tmp, "GET", session); //$NON-NLS-1$
196: return html;
197: } else {
198: xForm.append(xformHeader);
199: xForm.append(xformBody);
200: xForm.append("</html>"); //$NON-NLS-1$
201:
202: String html = transform(xForm.toString(),
203: "GET", session); //$NON-NLS-1$
204: return "<html><body dir=\"" + LocaleHelper.getTextDirection() + "\">" + html + "</body></html>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
205: }
206:
207: } else {
208: return null;
209: }
210:
211: }
212:
213: public static void createXFormControl(String fieldName,
214: Object defaultValues, String formName,
215: StringBuffer xformHeader, StringBuffer xformBody,
216: boolean visible) {
217:
218: // create some xform to represent this parameter...
219:
220: if (xformHeader.length() == 0) {
221: // this is the first parameter, need to create the header...
222: createXFormHeader(formName, xformHeader);
223: }
224:
225: setDefaultValues(fieldName, defaultValues, xformHeader);
226:
227: if (visible) {
228: xformBody
229: .append("<xf:input model=\"").append(formName).append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\"></xf:input>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
230: }
231:
232: }
233:
234: private static void setDefaultValues(String fieldName,
235: Object defaultValues, StringBuffer xformHeader) {
236:
237: xformHeader.append("<data xmlns=\"\">"); //$NON-NLS-1$
238: if (defaultValues instanceof String) {
239: xformHeader
240: .append("<").append(fieldName).append(">").append(XmlHelper.encode((String) defaultValues)).append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
241: } else if (defaultValues instanceof String[]) {
242: String values[] = (String[]) defaultValues;
243: for (int i = 0; i < values.length; i++) {
244: xformHeader
245: .append("<").append(fieldName).append(">").append(XmlHelper.encode(values[i])).append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
246: }
247: } else if (defaultValues instanceof Object[]) {
248: Object values[] = (String[]) defaultValues;
249: for (int i = 0; i < values.length; i++) {
250: xformHeader
251: .append("<").append(fieldName).append(">").append(XmlHelper.encode(values[i].toString())).append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
252: }
253: } else if (defaultValues == null) {
254: xformHeader
255: .append("<").append(fieldName).append("></").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
256: } else {
257: xformHeader
258: .append("<").append(fieldName).append(">").append(XmlHelper.encode(defaultValues.toString())).append("</").append(fieldName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
259: }
260:
261: xformHeader.append("</data>"); //$NON-NLS-1$
262:
263: }
264:
265: public static void createXFormControl(int type, String fieldName,
266: Object defaultValues, List values, Map displayNames,
267: String formName, StringBuffer xformHeader,
268: StringBuffer xformBody) {
269:
270: // If displaying a text box value might be null and we still want to display the text box
271: if (type != TYPE_TEXT && values == null) {
272: return;
273: }
274: // create some xform to represent this parameter...
275:
276: if (xformHeader.length() == 0) {
277: // this is the first parameter, need to create the header...
278: createXFormHeader(formName, xformHeader);
279: }
280:
281: // If the values is not null and if there is only one item in the list make it the default
282: if (values != null && values.size() == 1) {
283: defaultValues = XmlHelper.encode(values.get(0).toString());
284: }
285:
286: setDefaultValues(fieldName, defaultValues, xformHeader);
287:
288: String appearance = ""; //$NON-NLS-1$
289: if (type == TYPE_TEXT) {
290: xformBody
291: .append("<xf:input model=\"").append(formName).append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\"></xf:input>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
292: } else if (type == TYPE_RADIO || type == TYPE_SELECT
293: || type == TYPE_LIST) {
294: switch (type) {
295: case TYPE_RADIO:
296: appearance = "appearance=\"full\"";break; //$NON-NLS-1$
297: case TYPE_SELECT:
298: appearance = "";break; //$NON-NLS-1$
299: case TYPE_LIST:
300: appearance = "appearance=\"compact\"";break; //$NON-NLS-1$
301: }
302: xformBody
303: .append("<xf:select1 ").append(appearance).append(" model=\"").append(formName).append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
304: Iterator listIterator = values.iterator();
305: while (listIterator.hasNext()) {
306: String value = XmlHelper.encode(listIterator.next()
307: .toString());
308: String displayValue = (displayNames != null) ? XmlHelper
309: .encode((String) displayNames.get(value))
310: : value;
311: if (displayValue == null) {
312: displayValue = value;
313: }
314: xformBody
315: .append("<xf:item><xf:label>").append(displayValue).append("</xf:label><xf:value>").append(value).append("</xf:value></xf:item>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
316: }
317: xformBody.append("</xf:select1>"); //$NON-NLS-1$
318: } else if (type == TYPE_LIST_MULTI || type == TYPE_CHECK_MULTI
319: || type == TYPE_CHECK_MULTI_SCROLL
320: || type == TYPE_CHECK_MULTI_SCROLL_2_COLUMN
321: || type == TYPE_CHECK_MULTI_SCROLL_3_COLUMN
322: || type == TYPE_CHECK_MULTI_SCROLL_4_COLUMN) {
323: switch (type) {
324: case TYPE_CHECK_MULTI:
325: appearance = "appearance=\"full\"";break; //$NON-NLS-1$
326: case TYPE_LIST_MULTI:
327: appearance = "appearance=\"compact\"";break; //$NON-NLS-1$
328: case TYPE_CHECK_MULTI_SCROLL:
329: appearance = "appearance=\"full-scroll\" columns=\"1\"";break; //$NON-NLS-1$
330: case TYPE_CHECK_MULTI_SCROLL_2_COLUMN:
331: appearance = "appearance=\"full-scroll\" columns=\"2\"";break; //$NON-NLS-1$
332: case TYPE_CHECK_MULTI_SCROLL_3_COLUMN:
333: appearance = "appearance=\"full-scroll\" columns=\"3\"";break; //$NON-NLS-1$
334: case TYPE_CHECK_MULTI_SCROLL_4_COLUMN:
335: appearance = "appearance=\"full-scroll\" columns=\"4\"";break; //$NON-NLS-1$
336: }
337: xformBody
338: .append("<xf:select ").append(appearance).append(" model=\"").append(formName).append("\" id=\"").append(fieldName).append("\" ref=\"").append(fieldName).append("\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
339: Iterator listIterator = values.iterator();
340: while (listIterator.hasNext()) {
341: String value = XmlHelper.encode(listIterator.next()
342: .toString());
343: String displayValue = (displayNames != null) ? XmlHelper
344: .encode((String) displayNames.get(value))
345: : value;
346: if (displayValue == null) {
347: displayValue = value;
348: }
349: xformBody
350: .append("<xf:item><xf:label>").append(displayValue).append("</xf:label><xf:value>").append(value).append("</xf:value></xf:item>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
351: }
352: xformBody.append("</xf:select>"); //$NON-NLS-1$
353: }
354:
355: }
356:
357: }
|