Package de.innovationgate.wgpublisher.webtml.utils

Source Code of de.innovationgate.wgpublisher.webtml.utils.TMLForm

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA 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.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.webtml.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import javax.activation.DataSource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.Action;

import org.apache.commons.fileupload.FileItem;
import org.apache.log4j.Logger;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.Dom4JDriver;


import de.innovationgate.utils.ImageScaler;
import de.innovationgate.utils.TemporaryFile;
import de.innovationgate.utils.TransientMap;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.utils.Zipper;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGContent;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGFactory;
import de.innovationgate.webgate.api.WGHierarchicalDatabase;
import de.innovationgate.webgate.api.WGHierarchicalDatabaseEventCanceledException;
import de.innovationgate.webgate.api.WGHierarchicalDatabaseEventException;
import de.innovationgate.webgate.api.WGIllegalArgumentException;
import de.innovationgate.webgate.api.WGIllegalStateException;
import de.innovationgate.webgate.api.WGRelationData;
import de.innovationgate.wga.common.CodeCompletion;
import de.innovationgate.wga.common.beans.csconfig.v1.CSConfig;
import de.innovationgate.wga.modules.ModuleInstantiationException;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.expressions.ExpressionEngine;
import de.innovationgate.wgpublisher.expressions.ExpressionEngineFactory;
import de.innovationgate.wgpublisher.expressions.ExpressionResult;
import de.innovationgate.wgpublisher.expressions.tmlscript.RhinoExpressionEngine;
import de.innovationgate.wgpublisher.expressions.tmlscript.TMLScriptException;
import de.innovationgate.wgpublisher.hdb.HDBModel;
import de.innovationgate.wgpublisher.hdb.HDBModelException;
import de.innovationgate.wgpublisher.hdb.HDBModelParams;
import de.innovationgate.wgpublisher.services.ServicesFileItem;

@CodeCompletion(methodMode=CodeCompletion.MODE_EXCLUDE)
public class TMLForm {
 
  private String documentPath;
  private String formAction = null;
  private Logger log;
    //private boolean persistent = false;
   
    // contains TMLFormFields, mapped by fieldname
  private HashMap fields       = new HashMap();   
   
  private List errors     = new ArrayList();
  private Map _files      = new HashMap();

  private static final String FILE_SEPARATOR_WIN32   = "\\";
  private static final String FILE_SEPARATOR_UNIX   = "/";

  @CodeCompletion
  public static final String RELATION_NULLPLACE_HOLDER = "##NULL##";
     
  // contains not submitted form information, for e.g. id, validation, messages etc.
    private FormInfo _formInfo;
 
    // contains validation message by fieldname
    private Map _messages = new HashMap();
   
    // contains form global messages, mapped by condition
    // linkedHashmap to save order
    private Map _globalMessages = new LinkedHashMap();
   
    // contains custom messages
    private List _customMessages = new ArrayList();
   
    // flag if the form was validated in this request
    // resetted by root:tag
    private boolean _wasValidatedInThisRequest;
   
    /**
     * May be used to distinguish, if a TMLForm was submitted (true) or has just been defined for the current request
     */
    private boolean _submitted = false;
   
    /**
     * holds the created document for e.g. by storeinhdb()
     */
    private WGDocument _createdDoc = null;
 
  public WGDocument getcreateddoc() {
    return _createdDoc;
  }
 
  @CodeCompletion
  public TMLForm(FormInfo formInfo, TMLContext context, Logger log) throws WGAPIException {
   
    this.log = log;
    this.documentPath = context.getpath();
        this._formInfo = formInfo;
       
        if (_formInfo.getTargetContextPath() == null) {
            _formInfo.setTargetContextPath(context.getpath());
        }
   
  }
 
  @CodeCompletion
  public TMLForm(List fileItems, TMLContext context, Logger log, HttpServletRequest request) throws TMLException, WGAPIException, UnsupportedEncodingException {         

    this.log    = log;
    this.documentPath = context.getpath();
        this._submitted = true;
       
        Map submittedFields = new HashMap();     
      
    log.debug( "***************** TMLForm Submit Information *****************" );

    Iterator iter = fileItems.iterator();

    // put all FileItemObject into Map and put all transmitted fields into field map         
    while( iter.hasNext() ) {
      FileItem fi = (FileItem) iter.next();
      log.debug( "*********************** New FileItem ***********************" );
      log.debug( "FieldName: " + fi.getFieldName() + "  FileItemName: " + fi.getName() + "  Size: " + fi.getSize() + "  ContentType: " + fi.getContentType() );
     
      // File items
      if( !fi.isFormField()){
               
                    if (fi.getSize() > 0) {
                        parseFileItem(fi);
                    }
                   
      }
     
            // Standard form items
      else if(!fi.getFieldName().startsWith("$") ) {
               
                // Fields not yet defined in field list, single value HTML-Fields
        if( !submittedFields.containsKey(fi.getFieldName()) ) {
                    // create new TMLFormField and put in map
                    TMLFormField field = new TMLFormField(fi.getFieldName());
                    if (context.getwgacore().getCharacterEncoding() != null) {
                        field.addValue(fi.getString(context.getwgacore().getCharacterEncoding()));
                    } else {
                        field.addValue(fi.getString());
                    }
                    submittedFields.put(fi.getFieldName(), field);                     
        }
               
                // Fields already defined in field list, multi value HTML-Fields
        else {
                    // add value to valuelist
                    TMLFormField field = (TMLFormField) submittedFields.get(fi.getFieldName());
                    if (context.getwgacore().getCharacterEncoding() != null) {
                        field.addValue(fi.getString(context.getwgacore().getCharacterEncoding()));
                    } else {
                        field.addValue(fi.getString());
                    }                   
        }
      }
           
            // Special system items
      else if (fi.getFieldName().equals("$formaction")) {
                if (context.getwgacore().getCharacterEncoding() != null) {
                    this.formAction = fi.getString(context.getwgacore().getCharacterEncoding());
                } else {
                    this.formAction = fi.getString();
                }
       
      }
            else if( fi.getFieldName().equals("$forminfo") ) {
                try {
                    // get FormInfo from hidden field
                    // decrypt
                    byte[] serFormInfo = null;
                    if (context.getwgacore().getCharacterEncoding() != null) {
                        serFormInfo = context.getwgacore().getDesEncrypter().decrypt(fi.getString(context.getwgacore().getCharacterEncoding()));
                    } else {
                        serFormInfo = context.getwgacore().getDesEncrypter().decrypt(fi.getString());
                    }  
                   
                    if (serFormInfo != null) {
                     // unzip
                     String unzipped = Zipper.unzip(serFormInfo);
                     // deserialize
                     _formInfo = (FormInfo) new XStream(new Dom4JDriver()).fromXML(unzipped);
                    }
                    else {
                        log.error("Error in TMLForm. Field '$forminfo' was unreadable");
                    }
                }
                catch (Exception e) {
                    String errMsg = "Error parsing '$forminfo' for TMLForm.";                   
                    log.error(errMsg, e);
                    throw new TMLException(errMsg, e, false);
                }
            }           
    }
       
        if (_formInfo == null) {
            String errMsg = "Error in TMLForm. No field '$forminfo' was submitted.";
            log.error(errMsg);
            throw new TMLException(errMsg, false);
        }
       
        setDocumentPath(_formInfo.getTargetContextPath());
       
        processSubmittedFields(submittedFields);
       
        retrieveCustomFields();
       
        enforceFieldDefs();    
       
  }

    private void processSubmittedFields(Map submittedFields) {
        // if form is not in edit mode - ignore posted data
        if (!_formInfo.getMode().equals(FormInfo.EDIT_MODE)) {
            return;
        }               
        // iterate over submittedFields
        // if form support htmlInputs put all fields in fieldlist
        // if not put only enabled Fields in fieldlist       
        Iterator submittedIt = submittedFields.keySet().iterator();
        while (submittedIt.hasNext()) {
            String fieldname = (String) submittedIt.next();
            TMLFormField field = (TMLFormField) submittedFields.get(fieldname);
            if (_formInfo.containsFieldRegistration(fieldname)) {
                FieldReg fieldReg = _formInfo.getFieldRegistration(fieldname);
                // put only enabled fields in fieldlist
                if (fieldReg.getMode().equals(FieldReg.EDIT_MODE)) {
                    fields.put(field.getName(), field);
                }
            } else {
                if (_formInfo.isHtmlInput()) {
                    fields.put(field.getName(), field);
                } else if (!_formInfo.getHtmlInput().trim().equalsIgnoreCase("ignore")){
                    TMLContext.getThreadMainContext().addwarning("Formfield '" + field.getName() + "' ignored. - HTML-inputs are disabled on tmlform with id '" + _formInfo.getFormId() + "'.", false);
                }
            }
           
        }      
    }
   
   
    /**
     * retrieve not submitted fields (given only by tmlscript)
     * from formInfo and add them to fieldlist
     */
    private void retrieveCustomFields() {       
        Map customFields = _formInfo.getCustomFields();
        Iterator customFieldnames = customFields.keySet().iterator();
        while (customFieldnames.hasNext()) {
            String customFieldname = (String) customFieldnames.next();
            if (!fields.containsKey(customFieldname)) {
                fields.put(customFieldname, customFields.get(customFieldname));
            }
        }
    }
   
    /*
    private void removeNotRegisteredFields() {
        Iterator fieldnames = fields.keySet().iterator();
        while (fieldnames.hasNext()) {
            String fieldname = (String) fieldnames.next();
            if (!_formInfo.containsFieldRegistration(fieldname)) {
                fieldnames.remove();
            }
        }
    }*/

    private void parseFileItem(FileItem fi) {
        // create TempFileFolder and put TempFiles in them
        try {
            String fiName = fi.getName();
            // in case the file seperator is Win32 separator
            if (fiName.indexOf(FILE_SEPARATOR_WIN32) != -1) {
                fiName = fiName.substring(fiName.lastIndexOf(FILE_SEPARATOR_WIN32) + 1 );
            }
            // in case the file separator is UNIX-OS separator
            else {
                fiName = fiName.substring(fiName.lastIndexOf(FILE_SEPARATOR_UNIX) + 1 );
            }
           
          File uploadFile = createTempFormFile(fiName);
          fi.write( uploadFile );
          //B000048C2 - not necessary to call delete on exit wgaTempDir is deleted on wga shutdown
          //uploadFile.deleteOnExit();
          this._files.put(fiName, uploadFile );

          if( !fields.containsKey(fi.getFieldName()) ) {
                // create new TMLFormField and put in map
                TMLFormField field = new TMLFormField(fi.getFieldName());
                field.addValue(uploadFile.getName());
                fields.put(fi.getFieldName(), field);               
          }
          else {
                TMLFormField field = (TMLFormField) fields.get(fi.getFieldName());
                field.addValue(uploadFile.getName());               
          }
        }
        catch (IOException e) {
          e.printStackTrace();
        }
        catch (Exception e) {
          e.printStackTrace();
        }
    }

    private File createTempFormFile(String fiName) throws IOException {
        File tempDir = File.createTempFile("WGAFile", "", TMLContext.getThreadMainContext().getwgacore().getWgaTempDir() );
        log.debug("tempDir filepath: " + tempDir.getAbsolutePath());
        tempDir.delete();
        tempDir.mkdir();
        //B000048C2 - not necessary to call delete on exit wgaTempDir is deleted on wga shutdown
        //tempDir.deleteOnExit();
       
        File uploadFile = new File(tempDir, fiName );
        return uploadFile;
    }  
   
    public boolean validate() {
        // set validated flag for this request
        _wasValidatedInThisRequest = true;
       
        try {                       
            log.debug( "***************** TMLForm validation *****************" );
           
            TMLContext formContext = getFormContext();
           
            // We ensure that the validation context points to the current TMLForm (B00005E06)
            TMLContext validationContext = new TMLContext(formContext.getdocument(), formContext.getwgacore(), formContext.getprofile(), this);
            validationContext.importEnvironmentData(formContext);
           
            // keep validation status in formInfo
            _formInfo.setValidated(true);
   
            // clear messages
            this._messages.clear();
           
            // init expression engine
            RhinoExpressionEngine engine = (RhinoExpressionEngine) ExpressionEngineFactory.getEngine(ExpressionEngineFactory.ENGINE_TMLSCRIPT);
            if (engine == null) {
                TMLContext.getThreadMainContext().addwarning("Formvalidation cannot be processed. Error initializing tmlscript-engine.", false);
                return false;
            }       
           
            // validate each field
            Iterator fieldIt = fields.values().iterator();           
            boolean formIsValid = true;
            while (fieldIt.hasNext()) {
                TMLFormField field = (TMLFormField) fieldIt.next();
               
                // check if we have a registration for this field
                // we can only validate tml:input fields
                if (_formInfo.containsFieldRegistration(field.getName())) {
                    if (validateField(field, formContext, validationContext, engine) == false) {
                        formIsValid = false;
                    }
                }
            }
           
            // validate global validations (tml:validate tag)
            Iterator globalValidations = _formInfo.getFormValidations().keySet().iterator();
            while (globalValidations.hasNext()) {
                String expression = (String) globalValidations.next();
                FormInfo.FormValidation formValidation = (FormInfo.FormValidation) _formInfo.getFormValidations().get(expression);
                // check if formvalidation should be processed this time
                // all dependent fields (from attrib ifnoerror of tml:validate) are validated successfully
                boolean executeYet = true;
                Iterator ifnoerrorFields = formValidation.getIfnoerror().iterator();
                while (ifnoerrorFields.hasNext()) {
                    String fieldname = (String) ifnoerrorFields.next();
                    if (_messages.containsKey(fieldname)) {
                        executeYet = false;
                        break;
                    }
                }
                if (executeYet) {
                    ExpressionResult result = engine.evaluateExpression(expression, validationContext, ExpressionEngine.TYPE_EXPRESSION, buildValidationExpressionParams(null));               
                    if (result.isError()) {
                        formIsValid = false;
                        String errorMsg = "Validation-Expression could not be processed. Warning: " + result.getException().getMessage() + " - expression was: " + expression;
                        if (result.getException() != null) {
                            // See if there is a TMLFormValidationException "somewhere down there". If so we take it as negative validation result
                            Throwable cause = result.getException();
                            while (!(cause instanceof TMLFormValidationException) && cause.getCause() != null && cause.getCause() != cause) {
                                cause = cause.getCause();
                            }
                           
                            if (cause instanceof TMLFormValidationException) {
                                errorMsg = cause.getMessage();
                            }
                            else {
                                TMLContext.getThreadMainContext().addwarning(errorMsg, false);
                                TMLContext.getThreadMainContext().getlog().error("Error running validation expression", result.getException());
                            }
                        }

                        log.debug(errorMsg);                                      
                        _globalMessages.put(expression, errorMsg);
                        // clear given dependent fields
                        clearFields(formValidation.getCleariferror());
                    }
                    else if (result.isFalse()) {
                        formIsValid = false;
                        // resolve scriptlets in message
                        Map params = new HashMap();
                        params.put(RhinoExpressionEngine.PARAM_LEVEL, RhinoExpressionEngine.LEVEL_SCRIPTLETS);
                        String message = engine.resolveScriptlets(formValidation.getMessage(), validationContext, params);
                        _globalMessages.put(expression, message);                       
                        log.debug("Validation result for expression '" + expression + "' is '" + result.isTrue() + "'.");
                        // clear given dependent fields
                        clearFields(formValidation.getCleariferror());                       
                    } else if (result.isTrue()) {
                        log.debug("Validation result for expression '" + expression + "' is '" + result.isTrue() + "'.");
                    }           
                }
            }
               
            return formIsValid;
           
        } catch (Exception e) {
            TMLContext.getThreadMainContext().addwarning("Formvalidation failed. Exception: " + e.getMessage(), false);
            log.error("TMLFormValidation failed.", e);
            return false;
        }
    }

    private boolean validateField(TMLFormField field, TMLContext formContext, TMLContext validationContext, RhinoExpressionEngine engine) throws WGAPIException, ParseException {
        FieldReg fieldReg = _formInfo.getFieldRegistration(field.getName());
        String fieldname = field.getName();
        String validation = fieldReg.getValidation();
        boolean multiple = fieldReg.isMultiple();     
       
        boolean fieldIsValid = true;
             
        // if we have a validation, validate field
        if ( (validation != null) && (!validation.trim().equals("")) ) {
           
            // do not validate hashedpassword fields if hashed string was posted
            if (fieldReg.getType().equals("hashedpassword")) {
                // if entered and parsed value are equal a hashed string was posted
                String enteredValue = field.getFirstEnteredStringValue();
                Object parsedValue = field.getFirstParsedValue();
                if (enteredValue != null && !enteredValue.trim().equals("")) {                           
                    if (enteredValue.equals(parsedValue)) {
                        return true;
                    }
                }
            }
                                                           
            // set tmlscript variables containing the current field value
            setValidationVariables(validationContext, field, multiple);                       
           
            List validationList = new ArrayList();
            List messageList = new ArrayList();
           
            //if a validationdivider is set for this field, tokenize validation and message
            String msg = fieldReg.getMessage();
           
            if (fieldReg.getValidationdivider() != null) {
                validationList = WGUtils.deserializeCollection(validation, fieldReg.getValidationdivider());
                if (msg == null) {
                    messageList = Collections.nCopies(validationList.size(), TMLContext.getThreadMainContext().systemLabel("tmlform", "msg_failed_validation") + fieldReg.getName());
                }
                else {
                    messageList = WGUtils.deserializeCollection(msg, fieldReg.getValidationdivider());
                }
            }
            else {
                // add single validation and message
                validationList.add(validation);
                if (msg == null) {
                    msg = TMLContext.getThreadMainContext().systemLabel("tmlform", "msg_failed_validation") + fieldReg.getName();
                }
                messageList.add(msg);
            }
           
            //process validations for field              
            for (int i = 0; i < validationList.size(); i++) {
               
                String expression = (String) validationList.get(i);
               
                String message = "";
                if (i < messageList.size()) {
                    message = (String) messageList.get(i);
                    // resolve scriptlets in message
                    Map params = new HashMap();
                    params.put(RhinoExpressionEngine.PARAM_LEVEL, RhinoExpressionEngine.LEVEL_SCRIPTLETS);
                    message = engine.resolveScriptlets(message, validationContext, params);
                }
               
                ExpressionResult result = engine.evaluateExpression(expression, validationContext, ExpressionEngine.TYPE_EXPRESSION, buildValidationExpressionParams(fieldReg));               
                if (result.isError() || result.isFalse()) { 
                   
                    fieldIsValid = false;
                    String errorMsg = message;
                   
                    // Validation had an error itself, we put out the error cause instead of the validation message
                    if (result.isError()) {
                        errorMsg = "Validation-Expression could not be processed. Warning: " + result.getException().getMessage() + " - expression was: " + expression;
                        if (result.getException() != null) {
                            // See if there is a TMLFormValidationException "somewhere down there". If so we take it as negative validation result
                            Throwable cause = result.getException();
                            while (!(cause instanceof TMLFormValidationException) && cause.getCause() != null && cause.getCause() != cause) {
                                cause = cause.getCause();
                            }
                            if (cause instanceof TMLFormValidationException) {
                                errorMsg = cause.getMessage();
                            }
                            else {
                                formContext.addwarning(errorMsg, false);
                                formContext.getlog().error("Error running validation expression", result.getException());
                            }
                        }
                    }
                                       
                    if (WGUtils.isEmpty(errorMsg)) {
                        formContext.addwarning("No message defined for validation '" + expression + "'", false);
                    }
                   
                    log.debug(errorMsg);                                                  
                    _messages.put(fieldname, errorMsg);
                   
                    // clear field if type is hashedpassword
                    // to ensure the validation can be executed again
                    if (fieldReg.getType().equals("hashedpassword")) {
                       field.clear();
                    }
                    // clear given dependent fields
                    clearFields(fieldReg.getCleariferror());                                                      
                    break; // stop further validation of this field
                }
                else if (result.isTrue()) {
                    log.debug("Validation result for field '" + fieldReg.getName() + "' result of '" + expression + "' is '" + result.isTrue() + "'.");
                }                           
            }
        }
       
        // In WGA5 behaviour we automatically check for conversion errors and treat them like validation errors
        if (fieldIsValid && !WGUtils.isEmpty(field.getEnteredValues()) && CSConfig.versionComplianceIsAtLeast(getforminfo().getVersionCompliance(), CSConfig.VERSIONCOMPLIANCE_WGA50)) {
            if (!field.couldBeParsed()) {
                fieldIsValid = false;
               
                List labelParams = new ArrayList();
                labelParams.add(field.getName());
                labelParams.add(fieldReg.getType());
                labelParams.add(WGUtils.serializeCollection(field.getEnteredValues(), ", "));
                labelParams.add(fieldReg.getFormat());
                String message;
                if (fieldReg.getFormat() != null) {
                    message = getFormContext().systemLabel("tmlform", "msg_failed_conversion_formatted", labelParams);
                }
                else {
                    message = getFormContext().systemLabel("tmlform", "msg_failed_conversion", labelParams);
                }
               
                log.debug(message);
                _messages.put(fieldname, message);
                // clear given dependent fields
                clearFields(fieldReg.getCleariferror());  
            }
        }
       
        return fieldIsValid;
    }

    private Map buildValidationExpressionParams(FieldReg fieldReg) {
        Map exprParams = new HashMap();
        TMLAction.Locator actionLocator = null;
       
        StringBuffer scriptName = new StringBuffer();
        scriptName.append("WebTML-Form '").append(getformid()).append("' ");
       
        // Add form design information if available
        if (getforminfo().getDefinitionDatabase() != null && getforminfo().getDefinitionModule() != null) {
            scriptName.append("(WebTML-Module ").append(getforminfo().getDefinitionDatabase()).append("/").append(getforminfo().getDefinitionModule()).append(") ");
            actionLocator = new TMLAction.Locator(getforminfo().getDefinitionDatabase(), getforminfo().getDefinitionModule());
        }
       
        // Type of validation
        if (fieldReg != null) {
            scriptName.append("Field validation for '").append(fieldReg.getName()).append("'");
        }
        else {
            scriptName.append("Global validation");
        }
       
        // Set as params
        exprParams.put(RhinoExpressionEngine.PARAM_SCRIPTNAME, scriptName.toString());
        if (actionLocator != null) {
            exprParams.put(RhinoExpressionEngine.PARAM_ACTIONLOCATOR, actionLocator);                               
        }
        return exprParams;
    }
   
    /**
     * clears the given list of (String) fieldnames
     * @param fieldsToClear List of Strings (fieldnames) to clear
     */
    private void clearFields(List fieldsToClear) {
        Iterator it = fieldsToClear.iterator();
        while (it.hasNext()) {
            String fieldToClear = (String) it.next();
            if (fields.containsKey(fieldToClear)) {
                TMLFormField tmlFormFieldToClear = (TMLFormField) fields.get(fieldToClear);
                if (tmlFormFieldToClear != null) {
                    tmlFormFieldToClear.clear();
                }
            }
        }       
    }

    private void setValidationVariables(TMLContext context, TMLFormField field, boolean multiple) throws WGAPIException {
       
        context.setvar("$FIELDNAME", field.getName());
       
        if (!multiple) {
            String enteredValue = field.getFirstEnteredStringValue();
            Object parsedValue = field.getFirstParsedValue();
           
            context.setvar("$E_VALUE", enteredValue);
            context.setvar("$P_VALUE", parsedValue);
            log.debug("Field: " + field.getName() + " E_VALUE=" + enteredValue + " P_VALUE=" + parsedValue);
        }
       
        else {
            List enteredValues = field.getEnteredStringValues();
            List parsedValues = field.getParsedValues();
            context.setvar("$E_VALUE", enteredValues);
            context.setvar("$P_VALUE", parsedValues);
            log.debug("Field: " + field.getName() + " E_VALUE=" + WGUtils.serializeCollection(enteredValues, ",") + " P_VALUE=" + WGUtils.serializeCollection(parsedValues, ","));
        }
    }   
   
   
   
  public String getformid() {
    return _formInfo.getFormId();
  }

    /**
     * Iterate over lastRenderedFields, convert values by type and store as parsedValue,
     * fill empty fields
     */
  private void enforceFieldDefs() {       
        errors.clear();
       
        Iterator lastRenderedFields = _formInfo.getLastRenderedFormFields().iterator();
        String currentFieldname = "";
        FieldReg currentFieldReg = null;       

        while (lastRenderedFields.hasNext()) {

            currentFieldname   = (String) lastRenderedFields.next();
           
            if (currentFieldname.trim().equals("")) {
                continue;
            }
           
           
            currentFieldReg
                = _formInfo.getFieldRegistration(currentFieldname);  
             
            // if field is a unchecked checkbox or option the whole field is not submitted, empty these fields
     
            if ((currentFieldReg.getType().equalsIgnoreCase("checkbox") || currentFieldReg.getType().equalsIgnoreCase("radio") || currentFieldReg.getType().equalsIgnoreCase("boolean")) 
                    && !fields.containsKey(currentFieldReg.getName())) {
                TMLFormField field = new TMLFormField(currentFieldReg.getName());
               
                // Empty boolean fields default to false
                if (currentFieldReg.getType().equalsIgnoreCase("boolean")) {
                    field.setValue(Boolean.FALSE);
                }
               
                fields.put(currentFieldReg.getName(), field);       
      }          
           
            // if field is empty selectbox the field is not submited, empty these fields
            if (currentFieldReg.getType().equalsIgnoreCase("select") && !fields.containsKey(currentFieldReg.getName())) {
                fields.put(currentFieldReg.getName(), new TMLFormField(currentFieldReg.getName()));            
            }
           
            // if field was submitted during this post request (disabled html fields are not !!!)
      if (fields.containsKey(currentFieldReg.getName())) {
        try {
                    // convert entered values by type and store in parsedvalues
                    TMLFormField field = (TMLFormField) fields.get(currentFieldReg.getName());                                                       
                    parseField(currentFieldReg, field);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
        _formInfo.clearLastRenderedFormFields();
  }

    private void parseField(FieldReg fieldReg, TMLFormField field) throws ParseException {
        String format = fieldReg.getFormat();
       
        // we might have to trim field values
        if (fieldReg.isTrim() || _formInfo.isTrim()) {
            field.trim();
        }                   
       
        field.setMultiple(fieldReg.isMultiple());
       
        if( fieldReg.getType().equalsIgnoreCase("textarea") && fieldReg.isMultiple()) {
            field.setType(TMLFormField.TYPE_TEXTAREA);
            field.setMultipleDivider("\r\n");
            field.parse();
        }
        else if(fieldReg.getType().equalsIgnoreCase("date")) {
          convertDateValues(format, field);
        }
        else if(fieldReg.getType().equals("number")) {
          convertNumberValues(format, field);
        }
        else if(fieldReg.getType().equals("boolean")) {
            field.setType(TMLFormField.TYPE_BOOLEAN);
          field.parse();
        }
        else if (fieldReg.getType().equals("hashedpassword")) {
            convertHashedPassword(fieldReg, field);                           
        }
    }

    private void convertHashedPassword(FieldReg currentFieldReg, TMLFormField field)
        throws ParseException {
        field.setType(TMLFormField.TYPE_HASHEDPASSWORD);
        // check if field is already hashed
        TMLFormField hashedField = _formInfo.getHashedPasswordField(currentFieldReg.getName());
        if (hashedField != null) {
            // check if the user has changed the field
            Object postedValue = field.getFirstEnteredValue();
            Object renderedValue = hashedField.getFirstEnteredValue();
            if (postedValue != null && renderedValue != null) {
                if (postedValue.equals(renderedValue)) {
                    // user did not change the field,
                    // so we do not need to hash it
                } else {
                    // user changed the field, we have to hash
                    field.parse();
                }
            }
        } else {
            // field is not yet registered, so we have to hash
            field.parse();
        }
    }
   
    private void convertNumberValues(String format, TMLFormField field) {       
        field.setType(TMLFormField.TYPE_NUMBER);       
        field.setFormat(TMLContext.getThreadMainContext().getNumberFormat(format));
       
        try {
            field.parse();
        } catch (ParseException e) {
            String errMsg = "Cannot parse '" + field.getFirstEnteredStringValue() + " as number: " + e.getMessage();
            errors.add(errMsg);           
        }
    }   
   
    private void convertDateValues(String format, TMLFormField field) {
        field.setType(TMLFormField.TYPE_DATE);
        field.setFormat(TMLContext.getThreadMainContext().getDateFormat(format));
       
        try {
            field.parse();
        } catch (ParseException e) {
            String errMsg = "Cannot parse '" + field.getFirstEnteredStringValue() + "' as date format " + format + ": " + e.getMessage();
            errors.add(errMsg);           
        }
    }
    
 
  public List getfieldnames() {
    return new ArrayList(this.fields.keySet());
  }
 
  public boolean hasfield(String name) {
    return this.fields.containsKey(name);
  }
 
  public Object field(String name) { 
    if (hasfield(name)) {
            Object value = TMLContext.flattenList(fieldlist(name));
            if (value == null) {
                value = getFormContext().db().getNoItemBehaviour().getForTMLFormEmptyField();
            }
            return value;
        }
        else {
            return getFormContext().db().getNoItemBehaviour().getForTMLFormField();
        }
         
  }
 
  public void setfield(String name, Object value) throws ParseException {   
        TMLFormField field = (TMLFormFieldfields.get(name);
        if (field == null) {
            field = new TMLFormField(name);
        }
    field.setValue(value);
        fields.put(name, field);
               
        // put field also in formInfo.customFields,
        // to support not submitted but via tmlscript given fields
        _formInfo.addCustomField(field);
       
        // if we have a fieldReg -> we should parse the field
        if (_formInfo.containsFieldRegistration(name)) {
            FieldReg fieldReg = _formInfo.getFieldRegistration(name);
            this.parseField(fieldReg, field);
        }       
  }
 
  public void appendtofield(String name, Object value) throws ParseException {
        TMLFormField field = (TMLFormField) fields.get(name);
        if (field != null)  {
            field.addValue(value);
        } else {
          //B000045F6
          setfield(name, value);
        }
    }
 
  public void removefield(String name) {   
    this.fields.remove(name);
    //this.metaFields.remove(name);       
        _formInfo.removeFieldReg(name);
        // field might be a customfield, set by tmlscript  - so remove this too
        _formInfo.removeCustomField(name);  

        _formInfo.getLastRenderedFormFields().remove(name);
  }
 
  public List fieldlist(String name) {
    TMLFormField field = (TMLFormField) fields.get(name);
        if (field != null) {
            if (!field.couldBeParsed()) {
                return getFormContext().db().getNoItemBehaviour().getForTMLFormEmptyFieldList();
            } else {
                return field.getParsedValues();
            }
        } else {
            return getFormContext().db().getNoItemBehaviour().getForTMLFormFieldList();
       
  }

    private TMLContext getFormContext() {
        return TMLContext.getThreadMainContext().context(documentPath);
    }

    /**
     * retrieves the parsed value of the given fieldname
     * @param fieldname
     * @return parsed value (might be null)
     */
    public Object parsedvalue(String fieldname) {
        TMLFormField field = (TMLFormField) this.fields.get(fieldname);
        if (field != null) {
            if (field.isMultiple()) {
                return field.getParsedValues();
            } else {
                return field.getFirstParsedValue();
            }
        } else {
            return null;
        }
    }
   
    /**
     * retrieves the entered value of the given fieldname
     * @param fieldname
     * @return entered value (null if field is not found)
     */   
    public Object enteredvalue(String fieldname) {
        TMLFormField field = (TMLFormField) this.fields.get(fieldname);
        if (field != null) {
            if (field.isMultiple()) {
                return field.getEnteredStringValues();
            } else {
                return field.getFirstEnteredStringValue();
            }
        } else {
            return null;
        }
    }
   
    /**
     * returns the valuelist for the given fieldname
     * the valuelist contains the parsedvalue, if successfully parsed
     * otherwise the valuelist contains the enteredvalue
     * @param fieldname
     * @return
     */
    @CodeCompletion
    public List getEnteredOrParsedValues(String fieldname) {
        TMLFormField field = (TMLFormField) fields.get(fieldname);
        if (field != null) {
            List parsedValues = field.getParsedValues();
            if (parsedValues.contains(null)) {
                List enteredOrParsed = new ArrayList();
                for (int i=0; i<parsedValues.size(); i++) {                   
                    Object parsedValue = parsedValues.get(i);
                    if (parsedValue == null) {
                        enteredOrParsed.add(field.getEnteredValues().get(i));
                    } else {
                        enteredOrParsed.add(parsedValue);
                    }
                }
                return enteredOrParsed;
            } else {
                return parsedValues;
            }
        } else {
            return null;
        }
    }
 
  public boolean storeinprofile(TMLUserProfile profile) throws WGAPIException {
    this.log.debug("Storing formdata in profile document");
   
        // validate form
        if (!this.validate()) {
            //context.addwarning("Form validation during storeinprofile() failed. Formdata not saved.", false);
            return false;
        }       
       
    Iterator fieldNames = this.getfieldnames().iterator();
    if (profile == null) {
      TMLContext.getThreadMainContext().addwarning("Could not store form. Current user has no profile", false);
            return false;
    }
   
    String fieldName;
    while (fieldNames.hasNext()) {
      fieldName = (String) fieldNames.next();
            FieldReg fieldReg = _formInfo.getFieldRegistration(fieldName);
            if (fieldReg != null) {
                if (fieldReg.isStore()) {
                    profile.setitem(fieldName, this.fieldlist(fieldName));       
                }
            } else {
                // store fields without fieldreg e.g. customFields               
                profile.setitem(fieldName, this.fieldlist(fieldName));
           
    }
       
    return profile.save();
  }
 
  public boolean storeinprofile() throws WGAPIException {
      return storeinprofile(TMLContext.getThreadMainContext().getprofile());
  }
 
  public boolean storeindocument(WGDocument doc) throws WGAPIException {
   
        // validate form
        if (!this.validate()) {
            //context.addwarning("Form validation during storeindocument() failed. Formdata not saved.", false);
            return false;
        }
       
    transfertodocument(doc);
        return doc.save();
  }

    public void transfertodocument(WGDocument doc) throws WGAPIException {
        Iterator fieldNames = this.getfieldnames().iterator();
 
    String fieldName;
    while (fieldNames.hasNext()) {
      fieldName = (String) fieldNames.next();
            FieldReg fieldReg = _formInfo.getFieldRegistration(fieldName);
            TMLFormField field = (TMLFormField) fields.get(fieldName);
            if (fieldReg != null) {
                // store only fields with store==true
                if (fieldReg.isStore()) {
                   
                    // Metadata field
                    if (fieldReg.isMeta()) {
                        // B000041FA
                        if (field.couldBeParsed()) {
                            doc.setMetaData(fieldName.toUpperCase(),this.fieldlist(fieldName));
                        } else {
                            doc.setMetaData(fieldName.toUpperCase(), null);
                        }
                    }
                    else {
                        String relType = fieldReg.getRelationtype();
                       
                        // Relation field
                        if (relType != null && doc instanceof WGContent) {
                       
                            int relTypeInt = relType.equalsIgnoreCase("protected") ? WGContent.RELATIONTYPE_PROTECTED : WGContent.RELATIONTYPE_NORMAL;
                           
                            WGContent content = (WGContent) doc;
                          List<String> relationStrings = (List<String>) fieldlist(fieldName);
                         
                          // Relation field is filled
                          if (relationStrings.size() > 0 && !relationStrings.get(0).equals(RELATION_NULLPLACE_HOLDER)) {
                              if (fieldReg.isMultiple()) {
                                  content.clearRelationGroup(fieldName);
                                  for (String relStr : relationStrings) {
                                      TMLContext relationContext = gettargetcontext().context("docid:"+ relStr, false);
                                        if (relationContext != null) {
                                            content.addRelationToGroup(fieldName, relationContext.content(), relTypeInt);
                                        }  
                                  }
                              }
                              else {
                                  TMLContext relationContext = gettargetcontext().context("docid:"+ relationStrings.get(0), false);
                                  if (relationContext != null) {
                                    content.setRelation(fieldName, relationContext.content(), relTypeInt);
                                  }
                              }
                          }
                         
                          // Relation field is empty
                          else {
                              if (fieldReg.isMultiple()) {
                                  content.clearRelationGroup(fieldName);
                              }
                              else {
                                  content.removeRelation(fieldName);
                            }
                            }  
                        }
                       
                        // Plain item field
                        else {
                            doc.setItemValue(fieldName, this.fieldlist(fieldName));       
                        }
                    }
                }
            } else {
                // store fields without fieldreg e.g. customFields
                doc.setItemValue(fieldName, this.fieldlist(fieldName));
            }               
    }
    }

    private WGRelationData createRelationData(String relName, String relType, WGContent parentContent, String relationStr) throws WGAPIException, WGIllegalArgumentException {
        WGRelationData relData = null;
        TMLContext relationContext = gettargetcontext().context("docid:"+ relationStr, false);
        if (relationContext != null) {
          if (relType.equalsIgnoreCase("normal")) {
              relData = new WGRelationData(parentContent.getContentKey(), relName, relationContext.content().getStructKey(), relationContext.content().getLanguage().getName(), WGContent.RELATIONTYPE_NORMAL, null);
          }
          else if (relType.equalsIgnoreCase("protected")) {
              relData = new WGRelationData(parentContent.getContentKey(), relName, relationContext.content().getStructKey(), relationContext.content().getLanguage().getName(), WGContent.RELATIONTYPE_PROTECTED, null);
          }
          else {
            throw new WGIllegalArgumentException("Unknown relationtype '" + relType + "'.");
          }
        }
        else {
          throw new WGIllegalArgumentException("Relation context lookup failed for: field '" + relName + "' relationdata '" + relationStr + "'.");
        }
        return relData;
   
 
  public boolean storeincontent(WGContent content) throws WGAPIException {
    return storeindocument(content);
  }
 
  public boolean storeinhdb() throws WGAPIException, TMLScriptException {
      return storeinhdb(null);
  }
 
  public boolean storeinhdb(Object parameter) throws WGAPIException, TMLScriptException {
    // reset createdDoc - necessary for persistent forms
      _createdDoc = null;
     
        // validate form
        if (!this.validate()) {
            //context.addwarning("Form validation during storeindocument() failed. Formdata not saved.", false);
            return false;
        }
       
        // Get HDB instance
        TMLContext targetContext = gettargetcontext();
        WGHierarchicalDatabase hdb = WGHierarchicalDatabase.getInstance(targetContext.db().getDbReference());
        if (hdb == null) {
            throw new TMLScriptException("Cannot use tmlform.storeInHDB() in database " + targetContext.db().getDbReference() + " where HDB is not enabled");
        }
       
        // Create parameter object
        HDBModelParams params = new HDBModelParams(HDBModel.TYPE_CONTENT);
        params.setForm(this);
        params.setCustomParam(parameter);

        // Perform update
      String source = getforminfo().getSource();
      if (source.equals("content")) {
          WGContent content = gettargetcontext().content();
          params.setContentClass(content.getContentClass());
          try {
              hdb.updateContent(content, params);
              return true;
          }
          catch (WGHierarchicalDatabaseEventCanceledException e) {
              addmessage(e.getMessage());
              return false;
          }
      }
     
      // Perform create from here on
      if (!source.equals("none") && !source.equals("newcontent")) {
          throw new IllegalStateException("Cannot use tmlform.storeInHDB() when form source is not 'content', 'newcontent' or 'none'");
      }
     
        // Get desired content class
        String contentClass = getforminfo().getContentClass();
        if (contentClass == null) {
            throw new TMLScriptException("Cannot use tmlform.storeInHDB() on form " + getformid() + " that is defined without attribute 'contentclass'");
        }
        params.setContentClass(contentClass);
     
      // Get the model
      HDBModel model = (HDBModel) targetContext.db().getAttribute(WGACore.DBATTRIB_HDBMODEL);
      if (model == null) {
          throw new TMLScriptException("Cannot use tmlform.storeInHDB() in database " + targetContext.db().getDbReference() + " where HDB model is not available");
      }
     
      // Create the content
      try {
            _createdDoc = model.createContent(params, gettargetcontext().content());
            return true;
        }
      catch (WGHierarchicalDatabaseEventCanceledException e) {
            addmessage(e.getMessage());
            return false;
        }
        catch (HDBModelException e) {
            throw new TMLScriptException("Exception creating HDB model content", e);
        }
       
       
       
    }
   
  public boolean storeincontent() throws WGIllegalStateException, WGAPIException {
   
        // Retrieve the orginal doc for which the form was created
        TMLContext targetContext = gettargetcontext();
               
    if (targetContext != null) {
      return storeincontent(targetContext.content());
    }
    else {
      throw new WGIllegalStateException("Unable to store form, because it's target content could not be retrieved: " + documentPath);
    }
  }

  @CodeCompletion
    public TMLContext gettargetcontext() {
        TMLContext targetContext;
        targetContext = TMLContext.getThreadMainContext().context(documentPath, false);
        return targetContext;
    }
 
  public boolean storeinportlet(TMLPortlet portlet) throws WGAPIException {
    this.log.debug("Storing formdata in portlet");
   
    if (portlet == null) {
        TMLContext.getThreadMainContext().addwarning("Cannot find portlet to store data for storeinportlet()", false);
    }
       
        // validate form
        if (!this.validate()) {
            //
            return false;
        }       
   
    Iterator fieldNames = this.getfieldnames().iterator();
    String fieldName;
    while (fieldNames.hasNext()) {
      fieldName = (String) fieldNames.next();
            FieldReg fieldReg = _formInfo.getFieldRegistration(fieldName);
            if (fieldReg != null) {
                if (fieldReg.isStore()) {
                    portlet.setitem(fieldName, this.fieldlist(fieldName));       
                }
            } else {
                // store fields without fieldreg e.g. customFields               
                portlet.setitem(fieldName, this.fieldlist(fieldName));
            }
     
    }
    return portlet.save();
  }
 
  public boolean storeinportlet() throws WGAPIException {
      return storeinportlet(TMLContext.getThreadMainContext().getportlet());
  }

  @CodeCompletion
  public boolean writecsv( String destination, boolean includeHeaders, String delimiter ) {
    return CSVWriter.writeCSV( destination, this, includeHeaders, delimiter );
  }
   
  @CodeCompletion
    public boolean writecsv( String destination, boolean includeHeaders) {
        return CSVWriter.writeCSV( destination, this, includeHeaders, null );
    }


  /**
   * @return
   */
  public List geterrors() {
    return errors;
  }
 
  public List getfilenames() {
 
    return new ArrayList(_files.keySet());
  }
 
  public File getfile(String name) {
    return (File) _files.get(name);
  }
   
    public String getfiletext(String name) throws IOException {
       
        File file = (File) _files.get(name);
        if (file == null) {
            return null;
        }
       
        Reader reader = new BufferedReader(new FileReader(file));
        StringWriter writer = new StringWriter();
        WGUtils.inToOut(reader, writer, 2048);
        reader.close();
        return writer.toString();
       
    }

 
  public boolean attach( TMLUserProfile obj ) throws IOException, WGAPIException {
    return this.attach( obj.getprofile() );
  }
 
  public synchronized boolean attach( WGDocument doc , String altFileName ) throws IOException, WGAPIException {
   
    Iterator fileIter = _files.values().iterator();
   
    if( altFileName != null && !altFileName.equals("") ) {
      // only the first file, because -> only one filename given
      File file = (File) fileIter.next();
      if (!file.getName().equals(altFileName)) {
        TemporaryFile targetFile = new TemporaryFile(altFileName, new FileInputStream(file), WGFactory.getTempDir());
        targetFile.deleteOnEviction(doc.getDatabase().getSessionContext());
                boolean result = doc.attachFile( targetFile.getFile() );
                return result;
      }
      else {
          return doc.attachFile(file);
      }


    }
    else{   
      while( fileIter.hasNext() ) {
        File file = (File) fileIter.next();
        if (!doc.attachFile(file)) {
                    return false;
                }
      }
            return true;
    }
  }
 
  public boolean attach( WGDocument doc ) throws IOException, WGAPIException {   
    return attach( doc , null );   
  }
 
  public long attachmentsize( String fieldname ) {
    // fileSizeThreshold must be defined in Bytes   
    // getting name of uploaded file
    /*String tmlFormFile = fields.get(fieldname).toString().substring(
      1, fields.get(fieldname).toString().length() - 1 );*/
       
        TMLFormField field = (TMLFormField) fields.get(fieldname);
        if (field != null) {
            ArrayList values = (ArrayList) field.getEnteredValues();
            String filename = (String) values.get(0);

            Iterator fileIter = _files.values().iterator();
            while( fileIter.hasNext() ) {
                File file = (File) fileIter.next();
                if( file.getName().equalsIgnoreCase(filename) ) {
                    return file.length();
                }
            }           
        }            
    return -1;
  }
 
  @CodeCompletion
  public void attachimage( WGDocument doc, int size ) {
    String sSize = String.valueOf(size);  
    attachimage( doc, null , "true", null, sSize, sSize );
 
 
  @CodeCompletion
  public void attachimage( WGDocument doc, String fit2size, String compression, String width, String height ) {
    attachimage( doc, null , fit2size, compression, width, height );   
  }
   
  @CodeCompletion
    public void attachscaledimage(WGDocument doc, ImageScaler scaler, String targetFileName) throws IOException, WGAPIException {              
        getFormContext().attachscaledimage(doc, scaler, targetFileName);
    }
   
  @CodeCompletion
    public void attachscaledimage(WGDocument doc, ImageScaler scaler) throws IOException, WGAPIException {
        attachscaledimage(doc, scaler, null);
    }
   
   
   

   

 
  public void attachimage( WGDocument doc, String altFileName, String fit2size, String compression, String width, String height ) {
   
    if( width == null || width.equals("") ){
      width = "0";     
    }
    if( height == null || height.equals("") ){
      height = "0";     
    }
   
    Float fCompression = null;   
    if( compression != null && !compression.equals("") ){
      fCompression = new Float( compression );
    }
   
   
    try {   
      Iterator fileIter = _files.values().iterator();
     
      while( fileIter.hasNext() ) {
        File file = (File) fileIter.next();
        attachSingleFile(doc, altFileName, fit2size, width, height, fCompression, file);
      }
    }
    catch( Exception e ) {
      e.printStackTrace();
    }
  } 
 
 
 
  private void attachSingleFile(WGDocument doc, String altFileName, String keepRatio, String width, String height, Float fCompression, File file) throws NumberFormatException, IOException, WGAPIException, TMLScriptException, ModuleInstantiationException {

      // Determine if image file is of valid format
      String fileExt = file.getAbsolutePath().substring( file.getAbsolutePath().lastIndexOf(".") + 1 );
        if( !fileExt.equalsIgnoreCase("jpg") &&
          !fileExt.equalsIgnoreCase("jpeg") &&
          !fileExt.equalsIgnoreCase("bmp") &&
          !fileExt.equalsIgnoreCase("gif") &&
          !fileExt.equalsIgnoreCase("png") &&
          !fileExt.equalsIgnoreCase("tif") &&
          !fileExt.equalsIgnoreCase("tiff") &&
          !fileExt.equalsIgnoreCase("fpx") ) {
            WGFactory.getLogger().error( "WGA Imaging API Error: wrong file type!" );
            return;
        }
     
      // Determine target file
      String targetFileName = null;
      if( altFileName != null && !altFileName.equals("") && !file.getName().equals(altFileName) ) {
        targetFileName = altFileName;
      }
      else {
          String fileName = file.getName();
          targetFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".jpg";
      }
     
      TemporaryFile tempTargetFile = new TemporaryFile(targetFileName, null, WGFactory.getTempDir());
        tempTargetFile.deleteOnEviction(doc.getDatabase().getSessionContext());    
        File targetFile = tempTargetFile.getFile();
         
        ImageScaler scaler = TMLContext.getThreadMainContext().createimagescaler(file);
        scaler.useJPEGForOutput();       
        scaler.setQuality(fCompression.floatValue());
       
        scaler.scaleToSize(Integer.parseInt(width), Integer.parseInt(height), new Boolean(keepRatio).booleanValue());
       
        // Write scaled image to target file
        scaler.writeImage(targetFile);
       
        doc.attachFile(targetFile)
    }

    /**
   * @return
   */
  @CodeCompletion
  public String getformaction() {
     
    if(!WGUtils.isEmpty(formAction)) {
        return formAction;
    }
    else if (_formInfo.getDefaultAction() != null) {
        return String.valueOf(_formInfo.getDefaultAction());
    }
    else {
        return null;
    }
   
  }
 
  /**
   *
   */
  private void cleanupTempFormFiles() {
    Iterator fileIter = this._files.values().iterator();
   
    while( fileIter.hasNext() ) {
      File fileToDel   = (File) fileIter.next();
      cleanupTempFormFile(fileToDel);
     
    }
  }

    private boolean cleanupTempFormFile(File fileToDel) {
        File dirToDel  = fileToDel.getParentFile();
       
        if (fileToDel.exists()) {
          if (!fileToDel.delete()) {
              return false;
          }
        }
        if (dirToDel.exists()) {
            if (!dirToDel.delete()) {
                return false;
            }
        }
       
        return true;
    }

  /**
   * @param form
   */
  public void importForm(TMLForm form) {
             
    _files.putAll(form._files);
    fields.putAll(form.fields);
    //metaFields.addAll(form.metaFields);   
   
    formAction = form.formAction;
    errors = form.errors;   
    // documentPath = form.documentPath; // Document path should not be imported. Redefinition of it only possible via <tml:form>-Tag
 
        if (this._formInfo != null) {
            _formInfo.importFormInfo(form.getforminfo());
        } else {
            _formInfo = form.getforminfo();
        }
       
        //B00004D82
        _submitted = form._submitted;
       
        // To prevent the temporary form from deleting the imported files
        form._files.clear();
  }
 
  public void reset() {
        _formInfo.reset();
       
        cleanupTempFormFiles();
    _files.clear();
    errors.clear();
    fields.clear();
    getprocesscontext().clear();
        clearmessages();
    formAction = null;
    //B0000471A
    _submitted = false;
    //metaFields.clear(); 
    _createdDoc = null;
  }

 
  public void remove() {
    getFormContext().removetmlform(getformid());
  }
 
  /**
   * @return
   */
  public boolean isEditable() {
        if (_formInfo.getMode().equals(FormInfo.EDIT_MODE)) {
            return true;
        } else {
            return false;
        }
  }


  /**
   * @return
   */
  @CodeCompletion
  public String getDocumentPath() {
    return documentPath;
  }

  /**
   * @param string
   */
  public void setDocumentPath(String string) {
    documentPath = string;
  }

  /**
   * @return
   */
  @CodeCompletion
  public String getFormSource() {
        String formSource = _formInfo.getSource();
        if (formSource.trim().equals("")) {
            return null;
        } else {
            return formSource;
        }
  } 
   
    /**
     * orders messages by their fieldRegistration-order
     * this is necessary to display errors in form fields order
     * Nots: there is no guarantee that the order of submitted fields is correct
     *       so this reordering is better
     * @param messages
     * @return
     */
    private List orderByFieldRegistration(Map messages) {
        Iterator fieldRegs = _formInfo.getFieldRegistrations().iterator();
        ArrayList orderedMessages = new ArrayList();
        while (fieldRegs.hasNext()) {
            FieldReg fieldReg = (FieldReg) fieldRegs.next();
            if (messages.containsKey(fieldReg.getName())) {
                orderedMessages.add(messages.get(fieldReg.getName()));
            }
        }
        return orderedMessages;
    }
   
    /* (Kein Javadoc)
   * @see java.lang.Object#finalize()
   */
  protected void finalize() throws Throwable {
    cleanupTempFormFiles();
  }

    /**
     * @return Returns the persistent.
     */
    public boolean ispersistent() {       
        return _formInfo.isPersistent();
    }

    /**
     * @param persistent The persistent to set.
     */
    /*
    public void setPersistent(boolean persistent) {
        this.persistent = persistent;
    }*/
   
    /**
     * returns a list of all valdationmessages incl. custommessages
     * validation messages are ordered by their corresponding formfields
     * @return list
     */
    public List getmessages() {
        // merge field- and global messages
        ArrayList allMessages = new ArrayList();
        // reorder _messages because there is not guarantee that the HTML-Order is correct
        allMessages.addAll(this.orderByFieldRegistration(_messages));      
        allMessages.addAll(_globalMessages.values());
        allMessages.addAll(_customMessages);
        return allMessages;
    }
   
    /**
     * returns the message for the given field
     * @param field
     * @return message as String or null if there is no message or no such field
     */
    public String getmessage(String field) {
        return (String) this._messages.get(field);
    }
   
    /**
     * checks if the form has messages
     * can be used to check if validations failed
     * @return true/false
     */
    public boolean hasmessages() {
        boolean hasGlobalMessages = !_globalMessages.isEmpty();
        boolean hasFieldMessages = !_messages.isEmpty();
        boolean hasCustomMessages = !_customMessages.isEmpty();
        return (hasGlobalMessages || hasFieldMessages || hasCustomMessages);
    }
   
    /**
     * checks if there is a message for the given field
     * can be used to check if the given field has validation-errors
     * @param field
     * @return true/false
     */
    public boolean hasmessage(String field) {
        if (this._messages.get(field) != null) {
            return true;
        } else {
            return false;
        }
    }
   
    /**
     * adds a custommessage to the form
     * useful for customvalidations for e.g. in an tml:action
     * @param message
     */
    public void addmessage(String message) {
        _customMessages.add(message);
    }

    /**
     * checks if the given condition (globalFormValdation) failed
     * used by tml:validate to decide to display the message or not
     * @param condition
     * @return
     */
    @CodeCompletion
    public boolean conditionFailed(String condition) {
        return _globalMessages.containsKey(condition);
    }
   
    @CodeCompletion
    public FormInfo getforminfo() {
        return _formInfo;
    }

    @CodeCompletion
    public void setFormInfo(FormInfo formInfo) {
        _formInfo = formInfo;
    }
   
    /**
     * clears all messages (field-, global- and custom-messages)
     * and reset validation status
     */
    public void clearmessages() {
        _messages.clear();
        _globalMessages.clear();
        _customMessages.clear();
        // reset validation status
        _formInfo.setValidated(false);
    }
   
    /**
     * returns a list of fieldnames which contains validation errors
     * @return list containing fieldnames
     */
    public List getinvalidfields() {
        List list = new ArrayList();
        list.addAll(_messages.keySet());
        return list;
    }
   
    /**
     * returns the sourcetype ('content', 'portlet', etc.) of the form
     * @return
     */
    public String getsource() {
        return _formInfo.getSource();
    }
   
  public String source() {
        return getsource();
    }

    /**
     * returns the formmode
     * @return 'edit', 'view', 'readonly'
     */
    public String getmode() {
        return _formInfo.getMode();
    }
   
    public String mode() {
        return getmode();
    }

    @CodeCompletion
    public boolean wasValidatedInThisRequest() {
        return _wasValidatedInThisRequest;
    }
   
    @CodeCompletion
    public void setWasValidatedInThisRequest(boolean wasValidatedInThisRequest) {
        _wasValidatedInThisRequest = wasValidatedInThisRequest;
    }

    @CodeCompletion
    public void importServicesForm(de.innovationgate.wgaservices.types.Form form) {

        // Import fields
        Iterator<String> fieldNames = form.fieldNames().iterator();
        while (fieldNames.hasNext()) {
          String fieldname = fieldNames.next();
            try {
                setfield(fieldname, form.getField(fieldname).getValues());
            }
            catch (ParseException e) {
                // Should never happen, as services forms are not imported to forms with field registrations
                TMLContext.getThreadMainContext().addwarning("Cannot parse field " + fieldname + ": " + e.getMessage());
            }
        }
       
        // Import attachments
        Iterator<String> attNames = form.attachmentNames().iterator();
        while (attNames.hasNext()) {
          String name = attNames.next();
            DataSource data = form.attachmentData(name);
            ServicesFileItem servicesFileItem = new ServicesFileItem(name, data);
            parseFileItem(servicesFileItem);
        }
       
    }
   
    @CodeCompletion
    public de.innovationgate.wgaservices.types.Form exportServicesForm() throws IOException {

        de.innovationgate.wgaservices.types.Form servicesForm = new de.innovationgate.wgaservices.types.Form(getformid());
        servicesForm.setTrim(getforminfo().isTrim());
       
        // Export fields
        Iterator fieldNames = getfieldnames().iterator();
        while (fieldNames.hasNext()) {
            String fieldName = (String) fieldNames.next();
            servicesForm.setField(fieldName, new ArrayList<Object>(fieldlist(fieldName)));
        }
       
        // Export files
        Iterator files = _files.entrySet().iterator();
        while (files.hasNext()) {
            File file = (File) files.next();
            servicesForm.addFileAsAttachment(file);
        }
       
        return servicesForm;
       
    }

    /**
     * @return Returns the submitted.
     */
    public boolean issubmitted() {
        return _submitted;
    }
   
    public boolean removefile(String filename) {
       
        File file = (File) _files.remove(filename);
        if (file == null) {
            return false;
        }
       
        return cleanupTempFormFile(file);
    }
   
    public void addfile(File source, String fileName) throws IOException {
       
        File target = createTempFormFile(fileName);
        WGUtils.copyFile(source, target);
        this._files.put(fileName, target);
       
    }
   
    @CodeCompletion
    public String getprocessid() {
        return _formInfo.getProcessId();
    }
   
    public Map getprocesscontext() {
       
        Map <String, ProcessContext> contexts = TMLContext.getThreadMainContext().getEnvironment().getProcessContextRegistration();
        synchronized (contexts) {
            ProcessContext pContext = contexts.get(_formInfo.getProcessId());
            if (pContext == null) {
                pContext = new ProcessContext(_formInfo.getProcessId(), _formInfo.getFormId(), contexts);
            }
           
            return pContext;
        }
       
    }
   
    public boolean isempty(String fieldName) {
       
        FieldReg reg = getforminfo().getFieldRegistration(fieldName);
        if (reg != null && reg.getRelationtype() != null) {
            return RELATION_NULLPLACE_HOLDER.equals(field(fieldName));   
        }
        else {
            return WGUtils.isEmpty(field(fieldName));
        }
       
       
    }


}
TOP

Related Classes of de.innovationgate.wgpublisher.webtml.utils.TMLForm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.