0001: /*
0002: * File : $Source: /usr/local/cvs/alkacon/com.alkacon.opencms.formgenerator/src/com/alkacon/opencms/formgenerator/CmsForm.java,v $
0003: * Date : $Date: 2008-02-28 08:16:45 $
0004: * Version: $Revision: 1.7 $
0005: *
0006: * This file is part of the Alkacon OpenCms Add-On Module Package
0007: *
0008: * Copyright (c) 2007 Alkacon Software GmbH (http://www.alkacon.com)
0009: *
0010: * The Alkacon OpenCms Add-On Module Package is free software:
0011: * you can redistribute it and/or modify
0012: * it under the terms of the GNU General Public License as published by
0013: * the Free Software Foundation, either version 3 of the License, or
0014: * (at your option) any later version.
0015: *
0016: * The Alkacon OpenCms Add-On Module Package is distributed
0017: * in the hope that it will be useful,
0018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0020: * GNU General Public License for more details.
0021: *
0022: * You should have received a copy of the GNU General Public License
0023: * along with the Alkacon OpenCms Add-On Module Package.
0024: * If not, see http://www.gnu.org/licenses/.
0025: *
0026: * For further information about Alkacon Software GmbH, please see the
0027: * company website: http://www.alkacon.com.
0028: *
0029: * For further information about OpenCms, please see the
0030: * project website: http://www.opencms.org.
0031: */
0032:
0033: package com.alkacon.opencms.formgenerator;
0034:
0035: import org.opencms.configuration.CmsConfigurationException;
0036: import org.opencms.file.CmsFile;
0037: import org.opencms.file.CmsObject;
0038: import org.opencms.i18n.CmsMessages;
0039: import org.opencms.jsp.CmsJspActionElement;
0040: import org.opencms.util.CmsMacroResolver;
0041: import org.opencms.util.CmsStringUtil;
0042: import org.opencms.xml.content.CmsXmlContent;
0043: import org.opencms.xml.content.CmsXmlContentFactory;
0044: import org.opencms.xml.types.CmsXmlHtmlValue;
0045: import org.opencms.xml.types.I_CmsXmlContentValue;
0046:
0047: import java.util.ArrayList;
0048: import java.util.HashMap;
0049: import java.util.Iterator;
0050: import java.util.List;
0051: import java.util.Locale;
0052: import java.util.Map;
0053: import java.util.StringTokenizer;
0054:
0055: import org.apache.commons.fileupload.FileItem;
0056:
0057: /**
0058: * Represents an input form with all configured fields and options.<p>
0059: *
0060: * Provides the necessary information to create an input form, email messages and confirmation outputs.<p>
0061: *
0062: * @author Andreas Zahner
0063: * @author Thomas Weckert
0064: * @author Jan Baudisch
0065: *
0066: * @version $Revision: 1.7 $
0067: *
0068: * @since 7.0.4
0069: */
0070: public class CmsForm {
0071:
0072: /** Constant used as value in the XML content defining that the data target is database. */
0073: public static final String DATATARGET_DATABASE = "database";
0074:
0075: /** Constant used as value in the XML content defining that the data target is email. */
0076: public static final String DATATARGET_EMAIL = "email";
0077:
0078: /** Constant used as value in the XML content defining that the data target is database and email. */
0079: public static final String DATATARGET_EMAIL_DATABASE = "email-database";
0080:
0081: /** The macro to determine that field items for radio buttons and check boxes should be shown in a row. */
0082: public static final String MACRO_SHOW_ITEMS_IN_ROW = "%(row)";
0083:
0084: /** Mail type: html mail. */
0085: public static final String MAILTYPE_HTML = "html";
0086:
0087: /** Mail type: text mail. */
0088: public static final String MAILTYPE_TEXT = "text";
0089:
0090: /** Configuration node name for the optional captcha. */
0091: public static final String NODE_CAPTCHA = "FormCaptcha";
0092:
0093: /** Configuration node name for the optional captcha. */
0094: public static final String NODE_CAPTCHA_CHARACTERS = "Characters";
0095:
0096: /** Configuration node name for the optional captcha. */
0097: public static final String NODE_CAPTCHA_PRESET = "Preset";
0098:
0099: /** Configuration node name for the confirmation mail checkbox label text. */
0100: public static final String NODE_CONFIRMATIONMAILCHECKBOXLABEL = "ConfirmationCheckboxLabel";
0101:
0102: /** Configuration node name for the confirmation mail enabled node. */
0103: public static final String NODE_CONFIRMATIONMAILENABLED = "ConfirmationMailEnabled";
0104:
0105: /** Configuration node name for the confirmation mail input field node. */
0106: public static final String NODE_CONFIRMATIONMAILFIELD = "ConfirmationField";
0107:
0108: /** Configuration node name for the confirmation mail optional flag node. */
0109: public static final String NODE_CONFIRMATIONMAILOPTIONAL = "ConfirmationMailOptional";
0110:
0111: /** Configuration node name for the confirmation mail subject node. */
0112: public static final String NODE_CONFIRMATIONMAILSUBJECT = "ConfirmationMailSubject";
0113:
0114: /** Configuration node name for the confirmation mail text node. */
0115: public static final String NODE_CONFIRMATIONMAILTEXT = "ConfirmationMailText";
0116:
0117: /** Configuration node name for the optional nested data target. */
0118: public static final String NODE_DATATARGET = "DataTarget";
0119:
0120: /** Configuration node name for the transport field in the optional nested data target. */
0121: public static final String NODE_DATATARGET_FORMID = "FormId";
0122:
0123: /** Configuration node name for the transport field in the optional nested data target. */
0124: public static final String NODE_DATATARGET_TRANSPORT = "Transport";
0125:
0126: /** Configuration node name for the optional dynamic field class node. */
0127: public static final String NODE_DYNAMICFIELDCLASS = "DynamicFieldClass";
0128:
0129: /** Configuration node name for the Email node. */
0130: public static final String NODE_EMAIL = "Email";
0131:
0132: /** Configuration node name for the field value node. */
0133: public static final String NODE_FIELDDEFAULTVALUE = "FieldDefault";
0134:
0135: /** Configuration node name for the field error message node. */
0136: public static final String NODE_FIELDERRORMESSAGE = "FieldErrorMessage";
0137:
0138: /** Configuration node name for the field item node. */
0139: public static final String NODE_FIELDITEM = "FieldItem";
0140:
0141: /** Configuration node name for the field description node. */
0142: public static final String NODE_FIELDLABEL = "FieldLabel";
0143:
0144: /** Configuration node name for the field mandatory node. */
0145: public static final String NODE_FIELDMANDATORY = "FieldMandatory";
0146:
0147: /** Configuration node name for the field type node. */
0148: public static final String NODE_FIELDTYPE = "FieldType";
0149:
0150: /** Configuration node name for the field validation node. */
0151: public static final String NODE_FIELDVALIDATION = "FieldValidation";
0152:
0153: /** Configuration node name for the form attributes node. */
0154: public static final String NODE_FORMATTRIBUTES = "FormAttributes";
0155:
0156: /** Configuration node name for the form check page text node. */
0157: public static final String NODE_FORMCHECKTEXT = "CheckText";
0158:
0159: /** Configuration node name for the form confirmation text node. */
0160: public static final String NODE_FORMCONFIRMATION = "FormConfirmation";
0161:
0162: /** Configuration node name for the form field attributes node. */
0163: public static final String NODE_FORMFIELDATTRIBUTES = "FormFieldAttributes";
0164:
0165: /** Configuration node name for the form footer text node. */
0166: public static final String NODE_FORMFOOTERTEXT = "FormFooterText";
0167:
0168: /** Configuration node name for the form text node. */
0169: public static final String NODE_FORMTEXT = "FormText";
0170:
0171: /** Configuration node name for the input field node. */
0172: public static final String NODE_INPUTFIELD = "InputField";
0173:
0174: /** Configuration node name for the item description node. */
0175: public static final String NODE_ITEMDESCRIPTION = "ItemDescription";
0176:
0177: /** Configuration node name for the item selected node. */
0178: public static final String NODE_ITEMSELECTED = "ItemSelected";
0179:
0180: /** Configuration node name for the item value node. */
0181: public static final String NODE_ITEMVALUE = "ItemValue";
0182:
0183: /** Configuration node name for the Email bcc recipient(s) node. */
0184: public static final String NODE_MAILBCC = "MailBCC";
0185:
0186: /** Configuration node name for the Email cc recipient(s) node. */
0187: public static final String NODE_MAILCC = "MailCC";
0188:
0189: /** Configuration node name for the Email sender address node. */
0190: public static final String NODE_MAILFROM = "MailFrom";
0191:
0192: /** Configuration node name for the Email subject node. */
0193: public static final String NODE_MAILSUBJECT = "MailSubject";
0194:
0195: /** Configuration node name for the Email text node. */
0196: public static final String NODE_MAILTEXT = "MailText";
0197:
0198: /** Configuration node name for the Email recipient(s) node. */
0199: public static final String NODE_MAILTO = "MailTo";
0200:
0201: /** Configuration node name for the Email type node. */
0202: public static final String NODE_MAILTYPE = "MailType";
0203:
0204: /** Configuration node name for the optional form configuration. */
0205: public static final String NODE_OPTIONALCONFIGURATION = "OptionalFormConfiguration";
0206:
0207: /** Configuration node name for the optional confirmation mail configuration. */
0208: public static final String NODE_OPTIONALCONFIRMATION = "OptionalConfirmationMail";
0209:
0210: /** Configuration node name for the Show check page node. */
0211: public static final String NODE_SHOWCHECK = "ShowCheck";
0212:
0213: /** Configuration node name for the Show mandatory markings node. */
0214: public static final String NODE_SHOWMANDATORY = "ShowMandatory";
0215:
0216: /** Configuration node name for the Show reset button node. */
0217: public static final String NODE_SHOWRESET = "ShowReset";
0218:
0219: /** Configuration node name for the optional target URI. */
0220: public static final String NODE_TARGET_URI = "TargetUri";
0221:
0222: /** Request parameter name for the optional send confirmation email checkbox. */
0223: public static final String PARAM_SENDCONFIRMATION = "sendconfirmation";
0224:
0225: /** Resource type ID of XML content forms. */
0226: private static final String TYPE_NAME = "alkacon-webform";
0227:
0228: /** The captcha field. */
0229: protected CmsCaptchaField m_captchaField;
0230:
0231: /** list of possible configuration errors. */
0232: protected List m_configurationErrors;
0233:
0234: /** configuration value. */
0235: protected String m_confirmationMailCheckboxLabel;
0236:
0237: /** configuration value. */
0238: protected boolean m_confirmationMailEnabled;
0239:
0240: /** configuration value. */
0241: protected int m_confirmationMailField;
0242:
0243: /** configuration value. */
0244: protected boolean m_confirmationMailOptional;
0245:
0246: /** configuration value. */
0247: protected String m_confirmationMailSubject;
0248:
0249: /** configuration value. */
0250: protected String m_confirmationMailText;
0251:
0252: /** configuration value. */
0253: protected String m_confirmationMailTextPlain;
0254:
0255: /** Stores the form dynamic input fields. */
0256: protected List m_dynaFields;
0257:
0258: /** The class name for the dynamic field value resolver. */
0259: protected String m_dynamicFieldClass;
0260:
0261: /** Stores the form input fields. */
0262: protected List m_fields;
0263:
0264: /** Allows to access form fields internally by name. */
0265: protected Map m_fieldsByName;
0266:
0267: /** configuration value. */
0268: protected String m_formAction;
0269:
0270: /** configuration value. */
0271: protected String m_formAttributes;
0272:
0273: /** configuration value. */
0274: protected String m_formCheckText;
0275:
0276: /** configuration value. */
0277: protected String m_formConfirmationText;
0278:
0279: /** configuration value. */
0280: protected String m_formFieldAttributes;
0281:
0282: /** configuration value. */
0283: protected String m_formFooterText;
0284:
0285: /** The form id needed in case it is stored in the database. */
0286: protected String m_formId;
0287:
0288: /** configuration value. */
0289: protected String m_formText;
0290:
0291: /** If there is at least one mandatory field. */
0292: protected boolean m_hasMandatoryFields;
0293:
0294: /** configuration value. */
0295: protected String m_mailBCC;
0296:
0297: /** configuration value. */
0298: protected String m_mailCC;
0299:
0300: /** configuration value. */
0301: protected String m_mailFrom;
0302:
0303: /** configuration value. */
0304: protected String m_mailSubject;
0305:
0306: /** configuration value. */
0307: protected String m_mailSubjectPrefix;
0308:
0309: /** configuration value. */
0310: protected String m_mailText;
0311:
0312: /** configuration value. */
0313: protected String m_mailTextPlain;
0314:
0315: /** configuration value. */
0316: protected String m_mailTo;
0317:
0318: /** configuration value. */
0319: protected String m_mailType;
0320:
0321: /** The map of request parameters. */
0322: protected Map m_parameterMap;
0323:
0324: /** If the check page has to be shown. */
0325: protected boolean m_showCheck;
0326:
0327: /** If the text to explain mandatory fields has to be shown. */
0328: protected boolean m_showMandatory;
0329:
0330: /** If the reset button has to be shown. */
0331: protected boolean m_showReset;
0332:
0333: /** configuration value. */
0334: protected String m_targetUri;
0335:
0336: /** Flag to signal that data should be stored in the database - defaults to false. */
0337: protected boolean m_transportDatabase = false;
0338:
0339: /** Flag to signal that data should be sent by email - defaults to true. */
0340: protected boolean m_transportEmail = true;
0341:
0342: /**
0343: * Default constructor which parses the configuration file.<p>
0344: *
0345: * @param jsp the initialized CmsJspActionElement to access the OpenCms API
0346: * @param messages the localized messages
0347: * @param initial if true, field values are filled with values specified in the configuration file, otherwise from the request
0348: * @throws Exception if parsing the configuration fails
0349: */
0350: public CmsForm(CmsFormHandler jsp, CmsMessages messages,
0351: boolean initial) throws Exception {
0352:
0353: init(jsp, messages, initial, null, null);
0354: }
0355:
0356: /**
0357: * Constructor which parses the configuration file using a given configuration file URI.<p>
0358: *
0359: * @param jsp the initialized CmsJspActionElement to access the OpenCms API
0360: * @param messages the localized messages
0361: * @param initial if true, field values are filled with values specified in the configuration file, otherwise from the request
0362: * @param formConfigUri URI of the form configuration file, if not provided, current URI is used for configuration
0363: * @param formAction the desired action submitted by the form
0364: *
0365: * @throws Exception if parsing the configuration fails
0366: */
0367: public CmsForm(CmsFormHandler jsp, CmsMessages messages,
0368: boolean initial, String formConfigUri, String formAction)
0369: throws Exception {
0370:
0371: init(jsp, messages, initial, formConfigUri, formAction);
0372: }
0373:
0374: /**
0375: * Returns the resource type name of XML content forms.<p>
0376: *
0377: * @return the resource type name of XML content forms
0378: */
0379: public static String getStaticType() {
0380:
0381: return TYPE_NAME;
0382: }
0383:
0384: /**
0385: * Tests, if the captcha field (if configured at all) should be displayed on the check page.<p>
0386: *
0387: * @return true, if the captcha field should be displayed on the check page
0388: */
0389: public boolean captchaFieldIsOnCheckPage() {
0390:
0391: return getShowCheck();
0392: }
0393:
0394: /**
0395: * Tests, if the captcha field (if configured at all) should be displayed on the input page.<p>
0396: *
0397: * @return true, if the captcha field should be displayed on the input page
0398: */
0399: public boolean captchaFieldIsOnInputPage() {
0400:
0401: return !getShowCheck();
0402: }
0403:
0404: /**
0405: * Returns a list of field objects, inclusive dynamic fields, for the online form.<p>
0406: *
0407: * @return a list of field objects, inclusive dynamic fields
0408: */
0409: public List getAllFields() {
0410:
0411: List allFields = new ArrayList(m_fields);
0412: allFields.addAll(m_dynaFields);
0413: return allFields;
0414: }
0415:
0416: /**
0417: * Returns the (opt.) captcha field of this form.<p>
0418: *
0419: * @return the (opt.) captcha field of this form
0420: */
0421: public CmsCaptchaField getCaptchaField() {
0422:
0423: return m_captchaField;
0424: }
0425:
0426: /**
0427: * Returns the form configuration errors.<p>
0428: *
0429: * @return the form configuration errors
0430: */
0431: public List getConfigurationErrors() {
0432:
0433: return m_configurationErrors;
0434: }
0435:
0436: /**
0437: * Returns the label for the optional confirmation mail checkbox on the input form.<p>
0438: *
0439: * @return the label for the optional confirmation mail checkbox on the input form
0440: */
0441: public String getConfirmationMailCheckboxLabel() {
0442:
0443: return m_confirmationMailCheckboxLabel;
0444: }
0445:
0446: /**
0447: * Returns the index number of the input field containing the email address for the optional confirmation mail.<p>
0448: *
0449: * @return the index number of the input field containing the email address for the optional confirmation mail
0450: */
0451: public int getConfirmationMailField() {
0452:
0453: return m_confirmationMailField;
0454: }
0455:
0456: /**
0457: * Returns the subject of the optional confirmation mail.<p>
0458: *
0459: * @return the subject of the optional confirmation mail
0460: */
0461: public String getConfirmationMailSubject() {
0462:
0463: return m_confirmationMailSubject;
0464: }
0465:
0466: /**
0467: * Returns the text of the optional confirmation mail.<p>
0468: *
0469: * @return the text of the optional confirmation mail
0470: */
0471: public String getConfirmationMailText() {
0472:
0473: return m_confirmationMailText;
0474: }
0475:
0476: /**
0477: * Returns the plain text of the optional confirmation mail.<p>
0478: *
0479: * @return the plain text of the optional confirmation mail
0480: */
0481: public String getConfirmationMailTextPlain() {
0482:
0483: return m_confirmationMailTextPlain;
0484: }
0485:
0486: /**
0487: * Returns the class name for the dynamic field value resolver.<p>
0488: *
0489: * @return the class name for the dynamic field value resolver
0490: */
0491: public String getDynamicFieldClass() {
0492:
0493: return m_dynamicFieldClass;
0494: }
0495:
0496: /**
0497: * Returns the field with the given database label.<p>
0498: *
0499: * @param dbLabel the database label
0500: *
0501: * @return the field with the given database label or <code>null</code> if not found
0502: */
0503: public I_CmsField getFieldByDbLabel(String dbLabel) {
0504:
0505: Iterator it = getAllFields().iterator();
0506: while (it.hasNext()) {
0507: I_CmsField field = (I_CmsField) it.next();
0508: if (field.getDbLabel().equals(dbLabel)) {
0509: return field;
0510: }
0511: }
0512: return null;
0513: }
0514:
0515: /**
0516: * Returns a list of field objects for the online form.<p>
0517: *
0518: * @return a list of field objects for the online form
0519: */
0520: public List getFields() {
0521:
0522: return m_fields;
0523: }
0524:
0525: /**
0526: * Returns the value for a field specified by it's name (Xpath).<p>
0527: *
0528: * @param fieldName the field's name (Xpath)
0529: *
0530: * @return the field value, or null
0531: */
0532: public String getFieldStringValueByName(String fieldName) {
0533:
0534: I_CmsField field = (I_CmsField) m_fieldsByName.get(fieldName);
0535: if (field != null) {
0536: String fieldValue = field.getValue();
0537: if (field instanceof CmsDynamicField) {
0538: fieldValue = getDynamicFieldValue((CmsDynamicField) field);
0539: }
0540: return (fieldValue != null) ? fieldValue.trim() : "";
0541: }
0542:
0543: return "";
0544: }
0545:
0546: /**
0547: * Returns the global form attributes.<p>
0548: *
0549: * @return the global form attributes
0550: */
0551: public String getFormAttributes() {
0552:
0553: return m_formAttributes;
0554: }
0555:
0556: /**
0557: * Returns the form check text.<p>
0558: *
0559: * @return the form check text
0560: */
0561: public String getFormCheckText() {
0562:
0563: return m_formCheckText;
0564: }
0565:
0566: /**
0567: * Returns the form confirmation text.<p>
0568: *
0569: * @return the form confirmation text
0570: */
0571: public String getFormConfirmationText() {
0572:
0573: return m_formConfirmationText;
0574: }
0575:
0576: /**
0577: * Returns the optional form input field attributes.<p>
0578: *
0579: * @return the optional form input field attributes
0580: */
0581: public String getFormFieldAttributes() {
0582:
0583: return m_formFieldAttributes;
0584: }
0585:
0586: /**
0587: * Returns the form footer text.<p>
0588: *
0589: * @return the form footer text
0590: */
0591: public String getFormFooterText() {
0592:
0593: return m_formFooterText;
0594: }
0595:
0596: /**
0597: * Returns the id identifying the form entries that came from this form in the database.<p>
0598: *
0599: * @return the id identifying the form entries that came from this form in the database
0600: */
0601: public String getFormId() {
0602:
0603: return m_formId;
0604: }
0605:
0606: /**
0607: * Returns the form text.<p>
0608: *
0609: * @return the form text
0610: */
0611: public String getFormText() {
0612:
0613: return m_formText;
0614: }
0615:
0616: /**
0617: * Returns the mail bcc recipient(s).<p>
0618: *
0619: * @return the mail bcc recipient(s)
0620: */
0621: public String getMailBCC() {
0622:
0623: return m_mailBCC;
0624: }
0625:
0626: /**
0627: * Returns the mail cc recipient(s).<p>
0628: *
0629: * @return the mail cc recipient(s)
0630: */
0631: public String getMailCC() {
0632:
0633: return m_mailCC;
0634: }
0635:
0636: /**
0637: * Returns the mail sender address.<p>
0638: *
0639: * @return the mail sender address
0640: */
0641: public String getMailFrom() {
0642:
0643: return m_mailFrom;
0644: }
0645:
0646: /**
0647: * Returns the mail subject.<p>
0648: *
0649: * @return the mail subject
0650: */
0651: public String getMailSubject() {
0652:
0653: return m_mailSubject;
0654: }
0655:
0656: /**
0657: * Returns the mail subject prefix.<p>
0658: *
0659: * @return the mail subject prefix
0660: */
0661: public String getMailSubjectPrefix() {
0662:
0663: return m_mailSubjectPrefix;
0664: }
0665:
0666: /**
0667: * Returns the mail text.<p>
0668: *
0669: * @return the mail text
0670: */
0671: public String getMailText() {
0672:
0673: return m_mailText;
0674: }
0675:
0676: /**
0677: * Returns the mail text as plain text.<p>
0678: *
0679: * @return the mail text as plain text
0680: */
0681: public String getMailTextPlain() {
0682:
0683: return m_mailTextPlain;
0684: }
0685:
0686: /**
0687: * Returns the mail recipient(s).<p>
0688: *
0689: * @return the mail recipient(s)
0690: */
0691: public String getMailTo() {
0692:
0693: return m_mailTo;
0694: }
0695:
0696: /**
0697: * Returns the mail type ("text" or "html").<p>
0698: *
0699: * @return the mail type
0700: */
0701: public String getMailType() {
0702:
0703: return m_mailType;
0704: }
0705:
0706: /**
0707: * Returns if the check page should be shown.<p>
0708: *
0709: * @return true if the check page should be shown, otherwise false
0710: */
0711: public boolean getShowCheck() {
0712:
0713: return m_showCheck;
0714: }
0715:
0716: /**
0717: * Returns the target URI of this form.<p>
0718: *
0719: * This optional target URI can be used to redirect the user to an OpenCms page instead of displaying a confirmation
0720: * text from the form's XML content.<p>
0721: *
0722: * @return the target URI
0723: */
0724: public String getTargetUri() {
0725:
0726: return m_targetUri;
0727: }
0728:
0729: /**
0730: * Tests if a captcha field is configured for this form.<p>
0731: *
0732: * @return true, if a captcha field is configured for this form
0733: */
0734: public boolean hasCaptchaField() {
0735:
0736: return m_captchaField != null;
0737: }
0738:
0739: /**
0740: * Returns if the form has configuration errors.<p>
0741: *
0742: * @return true if the form has configuration errors, otherwise false
0743: */
0744: public boolean hasConfigurationErrors() {
0745:
0746: return m_configurationErrors.size() > 0;
0747: }
0748:
0749: /**
0750: * Returns true if at least one of the configured fields is mandatory.<p>
0751: *
0752: * @return true if at least one of the configured fields is mandatory, otherwise false
0753: */
0754: public boolean hasMandatoryFields() {
0755:
0756: return m_hasMandatoryFields;
0757: }
0758:
0759: /**
0760: * Tests if this form has a target URI specified.<p>
0761: *
0762: * This optional target URI can be used to redirect the user to an OpenCms page instead of displaying a confirmation
0763: * text from the form's XML content.<p>
0764: *
0765: * @return the target URI
0766: */
0767: public boolean hasTargetUri() {
0768:
0769: return CmsStringUtil.isNotEmpty(m_targetUri);
0770: }
0771:
0772: /**
0773: * Initializes the form configuration and creates the necessary form field objects.<p>
0774: *
0775: * @param jsp the initialized CmsJspActionElement to access the OpenCms API
0776: * @param messages the localized messages
0777: * @param initial if true, field values are filled with values specified in the XML configuration
0778: * @param formConfigUri URI of the form configuration file, if not provided, current URI is used for configuration
0779: * @param formAction the desired action submitted by the form
0780: *
0781: * @throws Exception if parsing the configuration fails
0782: */
0783: public void init(CmsFormHandler jsp, CmsMessages messages,
0784: boolean initial, String formConfigUri, String formAction)
0785: throws Exception {
0786:
0787: m_parameterMap = jsp.getParameterMap();
0788: // read the form configuration file from VFS
0789: if (CmsStringUtil.isEmpty(formConfigUri)) {
0790: formConfigUri = jsp.getRequestContext().getUri();
0791: }
0792: CmsFile file = jsp.getCmsObject().readFile(formConfigUri);
0793: CmsXmlContent content = CmsXmlContentFactory.unmarshal(jsp
0794: .getCmsObject(), file);
0795:
0796: // get current Locale
0797: Locale locale = jsp.getRequestContext().getLocale();
0798:
0799: // init member variables
0800: initMembers();
0801:
0802: m_formAction = formAction;
0803: m_fields = new ArrayList();
0804: m_dynaFields = new ArrayList();
0805: m_fieldsByName = new HashMap();
0806:
0807: // initialize general form configuration
0808: initFormGlobalConfiguration(content, jsp.getCmsObject(),
0809: locale, messages);
0810:
0811: // initialize the form input fields
0812: initInputFields(content, jsp, locale, messages, initial);
0813:
0814: // init. the optional captcha field
0815: initCaptchaField(jsp, content, locale, initial);
0816:
0817: // add the captcha field to the list of all fields, if the form has no check page
0818: if (captchaFieldIsOnInputPage() && (m_captchaField != null)) {
0819: addField(m_captchaField);
0820: }
0821: }
0822:
0823: /**
0824: * Tests if the check page was submitted.<p>
0825: *
0826: * @return true, if the check page was submitted
0827: */
0828: public boolean isCheckPageSubmitted() {
0829:
0830: return CmsFormHandler.ACTION_CONFIRMED.equals(m_formAction);
0831: }
0832:
0833: /**
0834: * Returns if the optional confirmation mail is enabled.<p>
0835: *
0836: * @return true if the optional confirmation mail is enabled, otherwise false
0837: */
0838: public boolean isConfirmationMailEnabled() {
0839:
0840: return m_confirmationMailEnabled;
0841: }
0842:
0843: /**
0844: * Returns if the confirmation mail if optional, i.e. selectable by the form submitter.<p>
0845: *
0846: * @return true if the confirmation mail if optional, i.e. selectable by the form submitter, otherwise false
0847: */
0848: public boolean isConfirmationMailOptional() {
0849:
0850: return m_confirmationMailOptional;
0851: }
0852:
0853: /**
0854: * Tests if the input page was submitted.<p>
0855: *
0856: * @return true, if the input page was submitted
0857: */
0858: public boolean isInputFormSubmitted() {
0859:
0860: return CmsFormHandler.ACTION_SUBMIT.equals(m_formAction);
0861: }
0862:
0863: /**
0864: * Returns if the mandatory marks and text should be shown.<p>
0865: *
0866: * @return true if the mandatory marks and text should be shown, otherwise false
0867: */
0868: public boolean isShowMandatory() {
0869:
0870: return m_showMandatory;
0871: }
0872:
0873: /**
0874: * Returns if the reset button should be shown.<p>
0875: *
0876: * @return true if the reset button should be shown, otherwise false
0877: */
0878: public boolean isShowReset() {
0879:
0880: return m_showReset;
0881: }
0882:
0883: /**
0884: * Returns true to signal that data should be stored in the database or false (default).<p>
0885: *
0886: * @return true to signal that data should be stored in the database or false (default)
0887: */
0888: public boolean isTransportDatabase() {
0889:
0890: return m_transportDatabase;
0891: }
0892:
0893: /**
0894: * Returns true to signal that data should be sent by email (default) or false.<p>
0895: *
0896: * @return true to signal that data should be sent by email (default) or false
0897: */
0898: public boolean isTransportEmail() {
0899:
0900: return m_transportEmail;
0901: }
0902:
0903: /**
0904: * Removes the captcha field from the list of all fields, if present.<p>
0905: */
0906: public void removeCaptchaField() {
0907:
0908: Iterator it = m_fields.iterator();
0909: while (it.hasNext()) {
0910: I_CmsField field = (I_CmsField) it.next();
0911: if (field instanceof CmsCaptchaField) {
0912: it.remove();
0913: m_fieldsByName.remove(field.getName());
0914: }
0915: }
0916: }
0917:
0918: /**
0919: * Sets if the mandatory marks and text should be shown.<p>
0920: *
0921: * @param showMandatory the setting for the mandatory marks
0922: */
0923: public void setShowMandatory(boolean showMandatory) {
0924:
0925: m_showMandatory = showMandatory;
0926: }
0927:
0928: /**
0929: * Sets if the reset button should be shown.<p>
0930: *
0931: * @param showReset the setting for the reset button
0932: */
0933: public void setShowReset(boolean showReset) {
0934:
0935: m_showReset = showReset;
0936: }
0937:
0938: /**
0939: * Adds a field to the form.<p>
0940: *
0941: * @param field the field to be added to the form
0942: */
0943: protected void addField(I_CmsField field) {
0944:
0945: if (field instanceof CmsDynamicField) {
0946: m_dynaFields.add(field);
0947: } else {
0948: m_fields.add(field);
0949: }
0950: // the fields are also internally backed in a map keyed by their field name
0951: m_fieldsByName.put(field.getName(), field);
0952: }
0953:
0954: /**
0955: * Creates the checkbox field to activate the confirmation mail in the input form.<p>
0956: *
0957: * @param messages the localized messages
0958: * @param initial if true, field values are filled with values specified in the XML configuration, otherwise values are read from the request
0959: *
0960: * @return the checkbox field to activate the confirmation mail in the input form
0961: */
0962: protected I_CmsField createConfirmationMailCheckbox(
0963: CmsMessages messages, boolean initial) {
0964:
0965: A_CmsField field = new CmsCheckboxField();
0966: field.setName(PARAM_SENDCONFIRMATION);
0967: field.setDbLabel(PARAM_SENDCONFIRMATION);
0968: field.setLabel(messages.key("form.confirmation.label"));
0969: // check the field status
0970: boolean isChecked = false;
0971: if (!initial
0972: && Boolean
0973: .valueOf(getParameter(PARAM_SENDCONFIRMATION))
0974: .booleanValue()) {
0975: // checkbox is checked by user
0976: isChecked = true;
0977: }
0978: // create item for field
0979: CmsFieldItem item = new CmsFieldItem(Boolean.toString(true),
0980: getConfirmationMailCheckboxLabel(), isChecked, false);
0981: List items = new ArrayList(1);
0982: items.add(item);
0983: field.setItems(items);
0984: return field;
0985: }
0986:
0987: /**
0988: * Checks if the given value is empty and returns in that case the default value.<p>
0989: *
0990: * @param value the configuration value to check
0991: * @param defaultValue the default value to return in case the value is empty
0992: * @return the checked value
0993: */
0994: protected String getConfigurationValue(String value,
0995: String defaultValue) {
0996:
0997: if (CmsStringUtil.isNotEmpty(value)) {
0998: return value;
0999: }
1000: return defaultValue;
1001: }
1002:
1003: /**
1004: * Resolves the value of a dynamic field.<p>
1005: *
1006: * @param field the field to resolve the value for
1007: *
1008: * @return the value of the given dynamic field
1009: */
1010: protected String getDynamicFieldValue(CmsDynamicField field) {
1011:
1012: if (field.getResolvedValue() == null) {
1013: try {
1014: I_CmsDynamicFieldResolver resolver = (I_CmsDynamicFieldResolver) Class
1015: .forName(getDynamicFieldClass()).newInstance();
1016: field.setResolvedValue(resolver.resolveValue(field,
1017: this ));
1018: } catch (Throwable e) {
1019: field.setResolvedValue(e.getLocalizedMessage());
1020: }
1021: }
1022: return field.getResolvedValue();
1023: }
1024:
1025: /**
1026: * Instantiates a new type instance of the given field type.<p>
1027: *
1028: * @param fieldType the field type to instantiate
1029: *
1030: * @return the instantiated field type or <code>null</code> is fails
1031: */
1032: protected I_CmsField getField(String fieldType) {
1033:
1034: return CmsFieldFactory.getSharedInstance().getField(fieldType);
1035: }
1036:
1037: /**
1038: * Returns the request parameter with the specified name.<p>
1039: *
1040: * @param parameter the parameter to return
1041: *
1042: * @return the parameter value
1043: */
1044: protected String getParameter(String parameter) {
1045:
1046: try {
1047: return ((String[]) m_parameterMap.get(parameter))[0];
1048: } catch (NullPointerException e) {
1049: return "";
1050: }
1051: }
1052:
1053: /**
1054: * Initializes the optional captcha field.<p>
1055: *
1056: * @param jsp the initialized CmsJspActionElement to access the OpenCms API
1057: * @param xmlContent the XML configuration content
1058: * @param locale the currently active Locale
1059: * @param initial if true, field values are filled with values specified in the XML configuration, otherwise values are read from the request
1060: */
1061: protected void initCaptchaField(CmsJspActionElement jsp,
1062: CmsXmlContent xmlContent, Locale locale, boolean initial) {
1063:
1064: boolean captchaFieldIsOnInputPage = captchaFieldIsOnInputPage();
1065: boolean displayCheckPage = captchaFieldIsOnCheckPage()
1066: && isInputFormSubmitted();
1067: boolean submittedCheckPage = captchaFieldIsOnCheckPage()
1068: && isCheckPageSubmitted();
1069:
1070: // Todo: read the captcha settings here, don't provide xmlcontent with form!!!
1071: if (captchaFieldIsOnInputPage || displayCheckPage
1072: || submittedCheckPage) {
1073:
1074: CmsObject cms = jsp.getCmsObject();
1075:
1076: I_CmsXmlContentValue xmlValueCaptcha = xmlContent.getValue(
1077: NODE_CAPTCHA, locale);
1078: if (xmlValueCaptcha != null) {
1079:
1080: // get the field label
1081: String xPathCaptcha = xmlValueCaptcha.getPath() + "/";
1082: String stringValue = xmlContent.getStringValue(cms,
1083: xPathCaptcha + NODE_FIELDLABEL, locale);
1084: String fieldLabel = getConfigurationValue(stringValue,
1085: "");
1086:
1087: // get the field value
1088: String fieldValue = "";
1089: if (!initial) {
1090: fieldValue = getParameter(CmsCaptchaField.C_PARAM_CAPTCHA_PHRASE);
1091: if (fieldValue == null) {
1092: fieldValue = "";
1093: }
1094: }
1095:
1096: // get the image settings from the XML content
1097: CmsCaptchaSettings captchaSettings = CmsCaptchaSettings
1098: .getInstance(jsp);
1099: captchaSettings.init(cms, xmlContent, locale);
1100: m_captchaField = new CmsCaptchaField(captchaSettings,
1101: fieldLabel, fieldValue);
1102: }
1103: }
1104: }
1105:
1106: /**
1107: * Initializes the general online form settings.<p>
1108: *
1109: * @param content the XML configuration content
1110: * @param cms the CmsObject to access the content values
1111: * @param locale the currently active Locale
1112: * @param messages the localized messages
1113: * @throws Exception if initializing the form settings fails
1114: */
1115: protected void initFormGlobalConfiguration(CmsXmlContent content,
1116: CmsObject cms, Locale locale, CmsMessages messages)
1117: throws Exception {
1118:
1119: // get the form text
1120: String stringValue = content.getStringValue(cms, NODE_FORMTEXT,
1121: locale);
1122: setFormText(getConfigurationValue(stringValue, ""));
1123: // get the form footer text
1124: stringValue = content.getStringValue(cms, NODE_FORMFOOTERTEXT,
1125: locale);
1126: setFormFooterText(getConfigurationValue(stringValue, ""));
1127: // get the form confirmation text
1128: stringValue = content.getStringValue(cms,
1129: NODE_FORMCONFIRMATION, locale);
1130: setFormConfirmationText(getConfigurationValue(stringValue, ""));
1131: // get the optional target URI
1132: stringValue = content.getStringValue(cms, NODE_TARGET_URI,
1133: locale);
1134: setTargetUri(getConfigurationValue(stringValue, ""));
1135: // get the mail from address
1136: stringValue = content
1137: .getStringValue(cms, NODE_MAILFROM, locale);
1138: setMailFrom(getConfigurationValue(stringValue, ""));
1139: // get the mail to address(es)
1140: stringValue = content.getStringValue(cms, NODE_MAILTO, locale);
1141: setMailTo(getConfigurationValue(stringValue, ""));
1142: // get the mail subject
1143: stringValue = content.getStringValue(cms, NODE_MAILSUBJECT,
1144: locale);
1145: setMailSubject(getConfigurationValue(stringValue, ""));
1146: // get the optional mail subject prefix from localized messages
1147: stringValue = messages.key("form.mailsubject.prefix");
1148: if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(stringValue)) {
1149: // prefix present, set it
1150: setMailSubjectPrefix(stringValue + " ");
1151: } else {
1152: // no prefix present
1153: setMailSubjectPrefix("");
1154: }
1155:
1156: CmsXmlHtmlValue mailTextValue = (CmsXmlHtmlValue) content
1157: .getValue(NODE_MAILTEXT, locale);
1158: if (mailTextValue != null) {
1159: // get the mail text as plain text
1160: stringValue = mailTextValue.getPlainText(cms);
1161: setMailTextPlain(getConfigurationValue(stringValue, ""));
1162: // get the mail text
1163: stringValue = mailTextValue.getStringValue(cms);
1164: setMailText(getConfigurationValue(stringValue, ""));
1165: } else {
1166: setMailTextPlain("");
1167: setMailText("");
1168: }
1169:
1170: // optional data target configuration
1171: String pathPrefix = NODE_DATATARGET + "/";
1172: stringValue = content.getStringValue(cms, pathPrefix
1173: + NODE_DATATARGET_TRANSPORT, locale);
1174: stringValue = getConfigurationValue(stringValue, "email");
1175: if (DATATARGET_EMAIL.equals(stringValue)) {
1176: this .setTransportEmail(true);
1177: this .setTransportDatabase(false);
1178: } else if (DATATARGET_DATABASE.equals(stringValue)) {
1179: this .setTransportEmail(false);
1180: this .setTransportDatabase(true);
1181: } else if (DATATARGET_EMAIL_DATABASE.equals(stringValue)) {
1182: this .setTransportEmail(true);
1183: this .setTransportDatabase(true);
1184:
1185: } else {
1186: // default behavior:
1187: this .setTransportEmail(true);
1188: this .setTransportDatabase(false);
1189: }
1190:
1191: stringValue = content.getStringValue(cms, pathPrefix
1192: + NODE_DATATARGET_FORMID, locale);
1193: setFormId(getConfigurationValue(stringValue, content.getFile()
1194: .getRootPath()));
1195:
1196: // optional configuration options
1197: pathPrefix = NODE_OPTIONALCONFIGURATION + "/";
1198:
1199: // get the mail type
1200: stringValue = content.getStringValue(cms, pathPrefix
1201: + NODE_MAILTYPE, locale);
1202: setMailType(getConfigurationValue(stringValue, MAILTYPE_HTML));
1203: // get the mail CC recipient(s)
1204: stringValue = content.getStringValue(cms, pathPrefix
1205: + NODE_MAILCC, locale);
1206: setMailCC(getConfigurationValue(stringValue, ""));
1207: // get the mail BCC recipient(s)
1208: stringValue = content.getStringValue(cms, pathPrefix
1209: + NODE_MAILBCC, locale);
1210: setMailBCC(getConfigurationValue(stringValue, ""));
1211: // get the form check page flag
1212: stringValue = content.getStringValue(cms, pathPrefix
1213: + NODE_SHOWCHECK, locale);
1214: setShowCheck(Boolean.valueOf(stringValue).booleanValue());
1215: // get the check page text
1216: stringValue = content.getStringValue(cms, pathPrefix
1217: + NODE_FORMCHECKTEXT, locale);
1218: setFormCheckText(getConfigurationValue(stringValue, ""));
1219: // get the dynamic fields class
1220: stringValue = content.getStringValue(cms, pathPrefix
1221: + NODE_DYNAMICFIELDCLASS, locale);
1222: setDynamicFieldClass(getConfigurationValue(stringValue, ""));
1223: // get the show mandatory setting
1224: stringValue = content.getStringValue(cms, pathPrefix
1225: + NODE_SHOWMANDATORY, locale);
1226: setShowMandatory(Boolean.valueOf(
1227: getConfigurationValue(stringValue, Boolean.TRUE
1228: .toString())).booleanValue());
1229: // get the show reset button setting
1230: stringValue = content.getStringValue(cms, pathPrefix
1231: + NODE_SHOWRESET, locale);
1232: setShowReset(Boolean.valueOf(
1233: getConfigurationValue(stringValue, Boolean.TRUE
1234: .toString())).booleanValue());
1235: // get the form attributes
1236: stringValue = content.getStringValue(cms, pathPrefix
1237: + NODE_FORMATTRIBUTES, locale);
1238: if (CmsStringUtil.isNotEmpty(stringValue)) {
1239: setFormAttributes(" " + stringValue);
1240: }
1241: // get the field attributes
1242: stringValue = content.getStringValue(cms, pathPrefix
1243: + NODE_FORMFIELDATTRIBUTES, locale);
1244: if (CmsStringUtil.isNotEmpty(stringValue)) {
1245: setFormFieldAttributes(" " + stringValue);
1246: } else {
1247: // no field attributes specified, check default field attributes
1248: String defaultAttributes = messages
1249: .key("form.field.default.attributes");
1250: if (CmsStringUtil.isNotEmpty(defaultAttributes)) {
1251: setFormFieldAttributes(" " + defaultAttributes);
1252: }
1253: }
1254:
1255: // optional confirmation mail nodes
1256: pathPrefix = NODE_OPTIONALCONFIRMATION + "/";
1257:
1258: // get the confirmation mail enabled flag
1259: stringValue = content.getStringValue(cms, pathPrefix
1260: + NODE_CONFIRMATIONMAILENABLED, locale);
1261: setConfirmationMailEnabled(Boolean.valueOf(stringValue)
1262: .booleanValue());
1263: // get other confirmation mail nodes only if confirmation mail is enabled
1264: if (isConfirmationMailEnabled()) {
1265: // get the confirmation mail subject
1266: stringValue = content.getStringValue(cms, pathPrefix
1267: + NODE_CONFIRMATIONMAILSUBJECT, locale);
1268: setConfirmationMailSubject(getConfigurationValue(
1269: stringValue, ""));
1270:
1271: mailTextValue = (CmsXmlHtmlValue) content.getValue(
1272: pathPrefix + NODE_CONFIRMATIONMAILTEXT, locale);
1273: if (mailTextValue != null) {
1274: // get the confirmation mail text
1275: stringValue = mailTextValue.getPlainText(cms);
1276: setConfirmationMailTextPlain(getConfigurationValue(
1277: stringValue, ""));
1278: stringValue = mailTextValue.getStringValue(cms);
1279: setConfirmationMailText(getConfigurationValue(
1280: stringValue, ""));
1281: } else {
1282: setConfirmationMailTextPlain("");
1283: setConfirmationMailText("");
1284: }
1285:
1286: // get the confirmation mail field index number
1287: stringValue = content.getStringValue(cms, pathPrefix
1288: + NODE_CONFIRMATIONMAILFIELD, locale);
1289: int fieldIndex = 1;
1290: try {
1291: fieldIndex = Integer.parseInt(getConfigurationValue(
1292: stringValue, "1")) - 1;
1293: } catch (Exception e) {
1294: // ignore this exception, use first field
1295: }
1296: setConfirmationMailField(fieldIndex);
1297: // get the confirmation mail optional flag
1298: stringValue = content.getStringValue(cms, pathPrefix
1299: + NODE_CONFIRMATIONMAILOPTIONAL, locale);
1300: setConfirmationMailOptional(Boolean.valueOf(stringValue)
1301: .booleanValue());
1302: // get the confirmation mail checkbox label text
1303: stringValue = content.getStringValue(cms, pathPrefix
1304: + NODE_CONFIRMATIONMAILCHECKBOXLABEL, locale);
1305: setConfirmationMailCheckboxLabel(getConfigurationValue(
1306: stringValue, messages
1307: .key("form.confirmation.checkbox")));
1308: }
1309: }
1310:
1311: /**
1312: * Initializes the field objects of the form.<p>
1313: *
1314: * @param content the XML configuration content
1315: * @param jsp the initialized CmsJspActionElement to access the OpenCms API
1316: * @param locale the currently active Locale
1317: * @param messages the localized messages
1318: * @param initial if true, field values are filled with values specified in the XML configuration, otherwise values are read from the request
1319: * @throws CmsConfigurationException if parsing the configuration fails
1320: */
1321: protected void initInputFields(CmsXmlContent content,
1322: CmsJspActionElement jsp, Locale locale,
1323: CmsMessages messages, boolean initial)
1324: throws CmsConfigurationException {
1325:
1326: CmsObject cms = jsp.getCmsObject();
1327: List fieldValues = content.getValues(NODE_INPUTFIELD, locale);
1328: int fieldValueSize = fieldValues.size();
1329: Map fileUploads = (Map) jsp.getRequest().getSession()
1330: .getAttribute(CmsFormHandler.ATTRIBUTE_FILEITEMS);
1331:
1332: for (int i = 0; i < fieldValueSize; i++) {
1333: I_CmsXmlContentValue inputField = (I_CmsXmlContentValue) fieldValues
1334: .get(i);
1335: String inputFieldPath = inputField.getPath() + "/";
1336:
1337: // get the field from the factory for the specified type
1338: String stringValue = content.getStringValue(cms,
1339: inputFieldPath + NODE_FIELDTYPE, locale);
1340: I_CmsField field = getField(stringValue);
1341:
1342: // create the field name
1343: String fieldName = inputFieldPath.substring(0,
1344: inputFieldPath.length() - 1);
1345: // cut off the xml content index ("[number]") and replace by "-number":
1346: int indexStart = fieldName.indexOf('[') + 1;
1347: String index = fieldName.substring(indexStart, fieldName
1348: .length() - 1);
1349: fieldName = new StringBuffer(fieldName.substring(0,
1350: indexStart - 1)).append('-').append(index)
1351: .toString();
1352:
1353: field.setName(fieldName);
1354: // get the field labels
1355: stringValue = content.getStringValue(cms, inputFieldPath
1356: + NODE_FIELDLABEL, locale);
1357: String locLabel = getConfigurationValue(stringValue, "");
1358: String dbLabel = locLabel;
1359: int pos = locLabel.indexOf("|");
1360: if (pos > -1) {
1361: locLabel = locLabel.substring(0, pos);
1362: if (pos + 1 < dbLabel.length()) {
1363: dbLabel = dbLabel.substring(pos + 1);
1364: }
1365: }
1366: field.setLabel(locLabel);
1367: field.setDbLabel(dbLabel);
1368:
1369: // validation error message
1370: stringValue = content.getStringValue(cms, inputFieldPath
1371: + NODE_FIELDERRORMESSAGE, locale);
1372: field.setErrorMessage(stringValue);
1373:
1374: // fill object members in case this is no hidden field
1375: if (!CmsHiddenField.class
1376: .isAssignableFrom(field.getClass())) {
1377: // get the field validation regular expression
1378: stringValue = content.getStringValue(cms,
1379: inputFieldPath + NODE_FIELDVALIDATION, locale);
1380: if (CmsEmailField.class.isAssignableFrom(field
1381: .getClass())
1382: && CmsStringUtil.isEmpty(stringValue)) {
1383: // set default email validation expression for confirmation email address input field
1384: field
1385: .setValidationExpression(CmsEmailField.VALIDATION_REGEX);
1386: } else {
1387: field
1388: .setValidationExpression(getConfigurationValue(
1389: stringValue, ""));
1390: }
1391: if (CmsFileUploadField.class.isAssignableFrom(field
1392: .getClass())) {
1393: if (fileUploads != null) {
1394: FileItem attachment = (FileItem) fileUploads
1395: .get(field.getName());
1396: if (attachment != null) {
1397: ((CmsFileUploadField) field)
1398: .setFileSize(attachment.get().length);
1399: }
1400: }
1401: }
1402: // get the field mandatory flag
1403: stringValue = content.getStringValue(cms,
1404: inputFieldPath + NODE_FIELDMANDATORY, locale);
1405: boolean isMandatory = Boolean.valueOf(stringValue)
1406: .booleanValue();
1407: field.setMandatory(isMandatory);
1408: if (isMandatory) {
1409: // set flag that determines if mandatory fields are present
1410: setHasMandatoryFields(true);
1411: }
1412:
1413: if (field.needsItems()) {
1414: // create items for checkboxes, radio buttons and selectboxes
1415: String fieldValue = content.getStringValue(cms,
1416: inputFieldPath + NODE_FIELDDEFAULTVALUE,
1417: locale);
1418: if (CmsStringUtil.isNotEmpty(fieldValue)) {
1419: // get items from String
1420: boolean showInRow = false;
1421: if (fieldValue
1422: .startsWith(MACRO_SHOW_ITEMS_IN_ROW)) {
1423: showInRow = true;
1424: fieldValue = fieldValue
1425: .substring(MACRO_SHOW_ITEMS_IN_ROW
1426: .length());
1427: }
1428: StringTokenizer T = new StringTokenizer(
1429: fieldValue, "|");
1430: List items = new ArrayList(T.countTokens());
1431: while (T.hasMoreTokens()) {
1432: String part = T.nextToken();
1433: // check preselection of current item
1434: boolean isPreselected = part.indexOf('*') != -1;
1435: String value = "";
1436: String label = "";
1437: String selected = "";
1438: int delimPos = part.indexOf(':');
1439: if (delimPos != -1) {
1440: // a special label text is given
1441: value = part.substring(0, delimPos);
1442: label = part.substring(delimPos + 1);
1443: } else {
1444: // no special label text present, use complete String
1445: value = part;
1446: label = value;
1447: }
1448:
1449: if (isPreselected) {
1450: // remove preselected flag marker from Strings
1451: value = CmsStringUtil.substitute(value,
1452: "*", "");
1453: label = CmsStringUtil.substitute(label,
1454: "*", "");
1455: }
1456:
1457: if (initial) {
1458: // only fill in values from configuration file if called initially
1459: if (isPreselected) {
1460: selected = Boolean.toString(true);
1461: }
1462: } else {
1463: // get selected flag from request for current item
1464: selected = readSelectedFromRequest(
1465: field, value);
1466: }
1467:
1468: // add new item object
1469: items
1470: .add(new CmsFieldItem(value, label,
1471: Boolean.valueOf(selected)
1472: .booleanValue(),
1473: showInRow));
1474:
1475: }
1476: field.setItems(items);
1477: } else {
1478: // no items specified for checkbox, radio button or selectbox
1479: throw new CmsConfigurationException(
1480: Messages
1481: .get()
1482: .container(
1483: Messages.ERR_INIT_INPUT_FIELD_MISSING_ITEM_2,
1484: field.getName(),
1485: field.getType()));
1486: }
1487: }
1488: }
1489: // get the field value
1490: if (initial
1491: && CmsStringUtil.isEmpty(getParameter(field
1492: .getName()))) {
1493: // only fill in values from configuration file if called initially
1494: if (!field.needsItems()) {
1495: String fieldValue = content.getStringValue(cms,
1496: inputFieldPath + NODE_FIELDDEFAULTVALUE,
1497: locale);
1498: if (CmsStringUtil.isNotEmpty(fieldValue)) {
1499: CmsMacroResolver resolver = CmsMacroResolver
1500: .newInstance().setCmsObject(cms)
1501: .setJspPageContext(jsp.getJspContext());
1502: field.setValue(resolver
1503: .resolveMacros(fieldValue));
1504: }
1505: } else {
1506: // for field that needs items,
1507: // the default value is used to set the items and not really a value
1508: field.setValue(null);
1509: }
1510: } else {
1511: // get field value from request for standard fields
1512: String[] parameterValues = (String[]) m_parameterMap
1513: .get(field.getName());
1514: StringBuffer value = new StringBuffer();
1515: if (parameterValues != null) {
1516: for (int j = 0; j < parameterValues.length; j++) {
1517: if (j != 0) {
1518: value.append(", ");
1519: }
1520: value.append(parameterValues[j]);
1521: }
1522: }
1523: field.setValue(value.toString());
1524: }
1525:
1526: addField(field);
1527: }
1528:
1529: // validate the form configuration
1530: validateFormConfiguration(messages);
1531:
1532: if (isConfirmationMailEnabled() && isConfirmationMailOptional()) {
1533: // add the checkbox to activate confirmation mail for customer
1534: I_CmsField confirmationMailCheckbox = createConfirmationMailCheckbox(
1535: messages, initial);
1536: addField(confirmationMailCheckbox);
1537: }
1538: }
1539:
1540: /**
1541: * Initializes the member variables.<p>
1542: */
1543: protected void initMembers() {
1544:
1545: setConfigurationErrors(new ArrayList());
1546: setFormAttributes("");
1547: setFormCheckText("");
1548: setFormConfirmationText("");
1549: setFormFieldAttributes("");
1550: setFormText("");
1551: setFormFooterText("");
1552: setMailBCC("");
1553: setMailCC("");
1554: setMailFrom("");
1555: setMailSubject("");
1556: setMailText("");
1557: setMailTextPlain("");
1558: setMailTo("");
1559: setMailType(MAILTYPE_HTML);
1560: setConfirmationMailSubject("");
1561: setConfirmationMailText("");
1562: setConfirmationMailTextPlain("");
1563: setShowMandatory(true);
1564: setShowReset(true);
1565: }
1566:
1567: /**
1568: * Marks the individual items of checkboxes, selectboxes and radiobuttons as selected depending on the given request parameters.<p>
1569: *
1570: * @param field the current field
1571: * @param value the value of the input field
1572: *
1573: * @return <code>"true"</code> if the current item is selected or checked, otherwise false
1574: */
1575: protected String readSelectedFromRequest(I_CmsField field,
1576: String value) {
1577:
1578: String result = "";
1579: if (field.needsItems()) {
1580: // select box or radio button or checkbox
1581: try {
1582: String[] values = (String[]) m_parameterMap.get(field
1583: .getName());
1584: for (int i = 0; i < values.length; i++) {
1585: if (CmsStringUtil.isNotEmpty(values[i])
1586: && values[i].equals(value)) {
1587: // mark this as selected
1588: result = Boolean.toString(true);
1589: }
1590: }
1591: } catch (Exception e) {
1592: // keep value null;
1593: }
1594:
1595: } else {
1596: // always display fields value arrays
1597: result = Boolean.toString(true);
1598: }
1599: return result;
1600: }
1601:
1602: /**
1603: * Sets the form configuration errors.<p>
1604: *
1605: * @param configurationErrors the form configuration errors
1606: */
1607: protected void setConfigurationErrors(List configurationErrors) {
1608:
1609: m_configurationErrors = configurationErrors;
1610: }
1611:
1612: /**
1613: * Sets the label for the optional confirmation mail checkbox on the input form.<p>
1614: *
1615: * @param confirmationMailCheckboxLabel the label for the optional confirmation mail checkbox on the input form
1616: */
1617: protected void setConfirmationMailCheckboxLabel(
1618: String confirmationMailCheckboxLabel) {
1619:
1620: m_confirmationMailCheckboxLabel = confirmationMailCheckboxLabel;
1621: }
1622:
1623: /**
1624: * Sets if the optional confirmation mail is enabled.<p>
1625: *
1626: * @param confirmationMailEnabled true if the optional confirmation mail is enabled, otherwise false
1627: */
1628: protected void setConfirmationMailEnabled(
1629: boolean confirmationMailEnabled) {
1630:
1631: m_confirmationMailEnabled = confirmationMailEnabled;
1632: }
1633:
1634: /**
1635: * Sets the index number of the input field containing the email address for the optional confirmation mail.<p>
1636: *
1637: * @param confirmationMailFieldName the name of the input field containing the email address for the optional confirmation mail
1638: */
1639: protected void setConfirmationMailField(
1640: int confirmationMailFieldName) {
1641:
1642: m_confirmationMailField = confirmationMailFieldName;
1643: }
1644:
1645: /**
1646: * Sets if the confirmation mail if optional, i.e. selectable by the form submitter.<p>
1647: *
1648: * @param confirmationMailOptional true if the confirmation mail if optional, i.e. selectable by the form submitter, otherwise false
1649: */
1650: protected void setConfirmationMailOptional(
1651: boolean confirmationMailOptional) {
1652:
1653: m_confirmationMailOptional = confirmationMailOptional;
1654: }
1655:
1656: /**
1657: * Sets the subject of the optional confirmation mail.<p>
1658: *
1659: * @param confirmationMailSubject the subject of the optional confirmation mail
1660: */
1661: protected void setConfirmationMailSubject(
1662: String confirmationMailSubject) {
1663:
1664: m_confirmationMailSubject = confirmationMailSubject;
1665: }
1666:
1667: /**
1668: * Sets the text of the optional confirmation mail.<p>
1669: *
1670: * @param confirmationMailText the text of the optional confirmation mail
1671: */
1672: protected void setConfirmationMailText(String confirmationMailText) {
1673:
1674: m_confirmationMailText = confirmationMailText;
1675: }
1676:
1677: /**
1678: * Sets the plain text of the optional confirmation mail.<p>
1679: *
1680: * @param confirmationMailTextPlain the plain text of the optional confirmation mail
1681: */
1682: protected void setConfirmationMailTextPlain(
1683: String confirmationMailTextPlain) {
1684:
1685: m_confirmationMailTextPlain = confirmationMailTextPlain;
1686: }
1687:
1688: /**
1689: * Sets the class name for the dynamic field value resolver.<p>
1690: *
1691: * @param className the class name to set
1692: */
1693: protected void setDynamicFieldClass(String className) {
1694:
1695: m_dynamicFieldClass = className;
1696: }
1697:
1698: /**
1699: * Sets the global form attributes.<p>
1700: *
1701: * @param formAttributes the global form attributes
1702: */
1703: protected void setFormAttributes(String formAttributes) {
1704:
1705: m_formAttributes = formAttributes;
1706: }
1707:
1708: /**
1709: * Sets the form check text.<p>
1710: *
1711: * @param formCheckText the form confirmation text
1712: */
1713: protected void setFormCheckText(String formCheckText) {
1714:
1715: m_formCheckText = formCheckText;
1716: }
1717:
1718: /**
1719: * Sets the form confirmation text.<p>
1720: *
1721: * @param formConfirmationText the form confirmation text
1722: */
1723: protected void setFormConfirmationText(String formConfirmationText) {
1724:
1725: m_formConfirmationText = formConfirmationText;
1726: }
1727:
1728: /**
1729: * Sets the optional form input field attributes.<p>
1730: *
1731: * @param formFieldAttributes the optional form input field attributes
1732: */
1733: protected void setFormFieldAttributes(String formFieldAttributes) {
1734:
1735: m_formFieldAttributes = formFieldAttributes;
1736: }
1737:
1738: /**
1739: * Sets the form footer text.<p>
1740: *
1741: * @param formFooterText the form text
1742: */
1743: protected void setFormFooterText(String formFooterText) {
1744:
1745: m_formFooterText = formFooterText;
1746: }
1747:
1748: /**
1749: * Sets the id identifying the form entries that came from this form in the database.<p>
1750: *
1751: * @param formId the id identifying the form entries that came from this form in the database
1752: */
1753: protected void setFormId(final String formId) {
1754:
1755: m_formId = formId;
1756: }
1757:
1758: /**
1759: * Sets the form text.<p>
1760: *
1761: * @param formText the form text
1762: */
1763: protected void setFormText(String formText) {
1764:
1765: m_formText = formText;
1766: }
1767:
1768: /**
1769: * Sets if at least one of the configured fields is mandatory.<p>
1770: *
1771: * @param hasMandatoryFields true if at least one of the configured fields is mandatory, otherwise false
1772: */
1773: protected void setHasMandatoryFields(boolean hasMandatoryFields) {
1774:
1775: m_hasMandatoryFields = hasMandatoryFields;
1776: }
1777:
1778: /**
1779: * Sets the mail bcc recipient(s).<p>
1780: *
1781: * @param mailBCC the mail bcc recipient(s)
1782: */
1783: protected void setMailBCC(String mailBCC) {
1784:
1785: m_mailBCC = mailBCC;
1786: }
1787:
1788: /**
1789: * Sets the mail cc recipient(s).<p>
1790: *
1791: * @param mailCC the mail cc recipient(s)
1792: */
1793: protected void setMailCC(String mailCC) {
1794:
1795: m_mailCC = mailCC;
1796: }
1797:
1798: /**
1799: * Sets the mail sender address.<p>
1800: *
1801: * @param mailFrom the mail sender address
1802: */
1803: protected void setMailFrom(String mailFrom) {
1804:
1805: m_mailFrom = mailFrom;
1806: }
1807:
1808: /**
1809: * Sets the mail subject.<p>
1810: *
1811: * @param mailSubject the mail subject
1812: */
1813: protected void setMailSubject(String mailSubject) {
1814:
1815: m_mailSubject = mailSubject;
1816: }
1817:
1818: /**
1819: * Sets the mail subject prefix.<p>
1820: *
1821: * @param mailSubjectPrefix the mail subject prefix
1822: */
1823: protected void setMailSubjectPrefix(String mailSubjectPrefix) {
1824:
1825: m_mailSubjectPrefix = mailSubjectPrefix;
1826: }
1827:
1828: /**
1829: * Sets the mail text.<p>
1830: *
1831: * @param mailText the mail text
1832: */
1833: protected void setMailText(String mailText) {
1834:
1835: m_mailText = mailText;
1836: }
1837:
1838: /**
1839: * Sets the mail text as plain text.<p>
1840: *
1841: * @param mailTextPlain the mail text as plain text
1842: */
1843: protected void setMailTextPlain(String mailTextPlain) {
1844:
1845: m_mailTextPlain = mailTextPlain;
1846: }
1847:
1848: /**
1849: * Sets the mail recipient(s).<p>
1850: *
1851: * @param mailTo the mail recipient(s)
1852: */
1853: protected void setMailTo(String mailTo) {
1854:
1855: m_mailTo = mailTo;
1856: }
1857:
1858: /**
1859: * Sets the mail type ("text" or "html").<p>
1860: *
1861: * @param mailType the mail type
1862: */
1863: protected void setMailType(String mailType) {
1864:
1865: m_mailType = mailType;
1866: }
1867:
1868: /**
1869: * Sets if the check page should be shown.<p>
1870: *
1871: * @param showCheck true if the check page should be shown, otherwise false
1872: */
1873: protected void setShowCheck(boolean showCheck) {
1874:
1875: m_showCheck = showCheck;
1876: }
1877:
1878: /**
1879: * Sets the target URI of this form.<p>
1880: *
1881: * This optional target URI can be used to redirect the user to an OpenCms page instead of displaying a confirmation
1882: * text from the form's XML content.<p>
1883: *
1884: * @param targetUri the target URI
1885: */
1886: protected void setTargetUri(String targetUri) {
1887:
1888: m_targetUri = targetUri;
1889: }
1890:
1891: /**
1892: * Sets if data should be stored to database or not (default).<p>
1893: *
1894: * @param transportDatabase flag to decide if data should be stored to database or not (default)
1895: */
1896: protected void setTransportDatabase(final boolean transportDatabase) {
1897:
1898: m_transportDatabase = transportDatabase;
1899: }
1900:
1901: /**
1902: * Sets if data should be sent by email (default) or not.<p>
1903: *
1904: * @param transportEmail flag to decide if data should be sent by email (default) or not
1905: */
1906: protected void setTransportEmail(final boolean transportEmail) {
1907:
1908: m_transportEmail = transportEmail;
1909: }
1910:
1911: /**
1912: * Validates the loaded online form configuration and creates a list of error messages, if necessary.<p>
1913: *
1914: * @param messages the localized messages
1915: */
1916: protected void validateFormConfiguration(CmsMessages messages) {
1917:
1918: if (isConfirmationMailEnabled()) {
1919: // confirmation mail is enabled, make simple field check to avoid errors
1920: I_CmsField confirmField;
1921: try {
1922: // try to get the confirmation email field
1923: confirmField = (I_CmsField) getFields().get(
1924: getConfirmationMailField());
1925: } catch (IndexOutOfBoundsException e) {
1926: // specified confirmation email field does not exist
1927: getConfigurationErrors()
1928: .add(
1929: messages
1930: .key("form.configuration.error.emailfield.notfound"));
1931: setConfirmationMailEnabled(false);
1932: return;
1933: }
1934: if (!CmsEmailField.class.isAssignableFrom(confirmField
1935: .getClass())) {
1936: // specified confirmation mail input field has wrong field type
1937: getConfigurationErrors()
1938: .add(
1939: messages
1940: .key("form.configuration.error.emailfield.type"));
1941: }
1942: }
1943: }
1944: }
|