/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.formgenerator/src/com/alkacon/opencms/formgenerator/dialog/CmsFormEditDialog.java,v $
* Date : $Date: 2011/06/08 13:35:02 $
* Version: $Revision: 1.8 $
*
* This file is part of the Alkacon OpenCms Add-On Module Package
*
* Copyright (c) 2010 Alkacon Software GmbH (http://www.alkacon.com)
*
* The Alkacon OpenCms Add-On Module Package 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.
*
* The Alkacon OpenCms Add-On Module Package 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 the Alkacon OpenCms Add-On Module Package.
* If not, see http://www.gnu.org/licenses/.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com.
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org.
*/
package com.alkacon.opencms.formgenerator.dialog;
import com.alkacon.opencms.formgenerator.CmsForm;
import com.alkacon.opencms.formgenerator.database.CmsFormDataAccess;
import com.alkacon.opencms.formgenerator.database.CmsFormDataBean;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.i18n.CmsEncoder;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.security.CmsPermissionSet;
import org.opencms.security.CmsRole;
import org.opencms.util.CmsStringUtil;
import org.opencms.widgets.CmsDisplayWidget;
import org.opencms.widgets.CmsInputWidget;
import org.opencms.widgets.CmsTextareaWidget;
import org.opencms.widgets.I_CmsWidget;
import org.opencms.workplace.CmsWidgetDialog;
import org.opencms.workplace.CmsWidgetDialogParameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import org.apache.commons.logging.Log;
/**
* Dialog to edit existing submitted data in the administration view.<p>
*
* @author Anja Roettgers
*
* @version $Revision: 1.8 $
*
* @since 7.0.4
*/
public class CmsFormEditDialog extends CmsWidgetDialog {
/** The length to cut the string text.*/
public static final int STRING_TRIM_SIZE = 200;
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsFormEditDialog.class);
/** Defines which pages are valid for this dialog. */
private static final String[] PAGES = {"page1"};
/** Localized messages keys prefix. */
private static final String WEBFORM_KEY_PREFIX = "webform_prefix";
/** Constant indicating that no upload folder was defined. */
private static final String WEBFORM_UPLOADFOLDER_NONE = "none";
/** a map with all fields and values. */
private HashMap<String, CmsFormDataEditBean> m_fields;
/** contains the original data of current entry.**/
private CmsFormDataBean m_formData;
/** Contains the id of the current entry.**/
private String m_paramEntryid;
/** Contains the id of the current form.**/
private String m_paramFormid;
/**
* Public constructor with JSP action element.<p>
*
* @param jsp an initialized JSP action element
*/
public CmsFormEditDialog(CmsJspActionElement jsp) {
super(jsp);
}
/**
* Public constructor with JSP variables.<p>
*
* @param context the JSP page context
* @param req the JSP request
* @param res the JSP response
*/
public CmsFormEditDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) {
this(new CmsJspActionElement(context, req, res));
}
/**
*
* @see org.opencms.workplace.CmsWidgetDialog#actionCommit()
*/
@Override
public void actionCommit() {
List<Throwable> errors = new ArrayList<Throwable>();
try {
// get the list of all fields
List<String> columnNames = CmsFormDataAccess.getInstance().readFormFieldNames(
m_paramFormid,
0,
Long.MAX_VALUE);
// for each field look if the value has changed and update the database
String column = null;
CmsFormDataEditBean data;
String value = null;
String orgValue;
for (int i = 0; i < columnNames.size(); i++) {
try {
// get for the field the old and new value
column = columnNames.get(i);
data = m_fields.get(column);
orgValue = m_formData.getFieldValue(column);
value = data.getValue();
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(
Messages.LOG_COMPARE_FORM_FIELDS_4,
new String[] {column, value, orgValue, m_paramEntryid}));
}
// compares the old and new value and update the database if not identical
if (!compareValues(orgValue, value) || ((value != null) && (value.trim().length() == 0))) {
CmsFormDataAccess.getInstance().updateFieldValue(
Integer.parseInt(m_paramEntryid),
column,
value);
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(
Messages.LOG_WRITE_FORM_FIELDS_3,
column,
value,
m_paramEntryid));
}
}
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(Messages.get().getBundle().key(
Messages.ERR_WRITE_FORM_FIELDS_3,
column,
value,
m_paramEntryid));
}
errors.add(new CmsException(Messages.get().container(
Messages.ERR_WRITE_FORM_FIELDS_3,
column,
value,
m_paramEntryid)));
}
}
} catch (Exception ex) {
errors.add(ex);
}
// set the list of errors to display when saving failed
setCommitErrors(errors);
}
/**
* Returns the paramEntryid.<p>
*
* @return the paramEntryid
*/
public String getParamEntryid() {
return m_paramEntryid;
}
/**
* Returns the formId.<p>
*
* @return the formId
*/
public String getParamFormid() {
return m_paramFormid;
}
/**
*
* @see org.opencms.workplace.CmsWorkplace#keyDefault(java.lang.String, java.lang.String)
*/
@Override
public String keyDefault(String keyName, String defaultValue) {
return getMessages().keyDefault(keyName, CmsStringUtil.escapeHtml(defaultValue));
}
/**
* Sets the paramEntryid.<p>
*
* @param paramEntryid the paramEntryid to set
*/
public void setParamEntryid(String paramEntryid) {
m_paramEntryid = paramEntryid;
}
/**
* Sets the formId.<p>
*
* @param formId the formId to set
*/
public void setParamFormid(String formId) {
if (formId == null) {
formId = "";
}
m_paramFormid = formId;
}
/**
*
* @see org.opencms.workplace.CmsWidgetDialog#defineWidgets()
*/
@Override
protected void defineWidgets() {
try {
setKeyPrefix(WEBFORM_KEY_PREFIX);
addStaticWidgets();
addDynamicWidgets();
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(Messages.get().container(Messages.ERR_SHOW_EDIT_FORM_FIELDS_1, m_paramEntryid));
}
}
}
/**
* @see org.opencms.workplace.CmsWidgetDialog#getPageArray()
*/
@Override
protected String[] getPageArray() {
return PAGES;
}
/**
* @see org.opencms.workplace.CmsWorkplace#initMessages()
*/
@Override
protected void initMessages() {
// add specific dialog resource bundle
addMessages(Messages.get().getBundleName());
super.initMessages();
}
/**
* @see org.opencms.workplace.CmsWidgetDialog#validateParamaters()
*/
@Override
protected void validateParamaters() throws Exception {
if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_paramEntryid)
|| CmsStringUtil.isEmptyOrWhitespaceOnly(m_paramFormid)) {
throw new Exception();
}
m_formData = CmsFormDataAccess.getInstance().readForm(Integer.parseInt(m_paramEntryid));
}
/**
* Creates the dynamic widgets for the current submitted data for each field.<p>
*
* @throws Exception if something goes wrong
*/
private void addDynamicWidgets() throws Exception {
if (m_fields == null) {
m_fields = new HashMap<String, CmsFormDataEditBean>();
}
// get the list of all fields
List<String> columnNames = CmsFormDataAccess.getInstance().readFormFieldNames(m_paramFormid, 0, Long.MAX_VALUE);
// determine if the columns can be edited by the current user
boolean editable;
try {
CmsResource formFile = getCms().readResource(m_formData.getResourceId());
editable = OpenCms.getRoleManager().hasRole(getCms(), CmsRole.DATABASE_MANAGER)
|| getCms().hasPermissions(formFile, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL);
} catch (CmsException e) {
// error reading form resource, only check roles of current user
editable = OpenCms.getRoleManager().hasRole(getCms(), CmsRole.DATABASE_MANAGER);
}
String uploadFolder = OpenCms.getModuleManager().getModule(CmsForm.MODULE_NAME).getParameter(
CmsForm.MODULE_PARAM_UPLOADFOLDER,
WEBFORM_UPLOADFOLDER_NONE);
// for each column create a widget
String column;
String value;
CmsFormDataEditBean edit;
for (int i = 0; i < columnNames.size(); i++) {
// get the entry and fill the columns
column = columnNames.get(i);
value = m_formData.getFieldValue(column);
if (CmsStringUtil.isEmpty(value)) {
value = "";
}
edit = createEditEntry(value, uploadFolder, editable);
addWidget(new CmsWidgetDialogParameter(edit, "value", column, "", PAGES[0], edit.getWidget(), 0, 1));
m_fields.put(column, edit);
}
}
/**
* Creates the static widgets for the current submitted data.<p>
*
* @throws Exception if something goes wrong
*/
private void addStaticWidgets() throws Exception {
// add the id widget
CmsFormDataEditBean edit = new CmsFormDataEditBean(m_formData.getFormId(), null);
addWidget(new CmsWidgetDialogParameter(
edit,
"value",
key(Messages.GUI_COLUMN_FIELDS_ID_0),
"",
PAGES[0],
new CmsDisplayWidget(),
1,
1));
// add the created date widget
edit = new CmsFormDataEditBean(Messages.get().getBundle().getDateTime(m_formData.getDateCreated()), null);
addWidget(new CmsWidgetDialogParameter(
edit,
"value",
key(Messages.GUI_COLUMN_FIELDS_DATE_0),
"",
PAGES[0],
new CmsDisplayWidget(),
1,
1));
// add the resource widget
String path;
try {
path = getCms().readResource(m_formData.getResourceId()).getRootPath();
} catch (Exception e) {
path = m_formData.getResourceId().toString();
}
edit = new CmsFormDataEditBean(path, null);
addWidget(new CmsWidgetDialogParameter(
edit,
"value",
key(Messages.GUI_COLUMN_FIELDS_RESOURCE_0),
"",
PAGES[0],
new CmsDisplayWidget(),
1,
1));
}
/**
* Compares the given values if they are identical.<p>
*
* @param value1 the first string can also be <code>null</code>
* @param value2 the second string can also be <code>null</code>
*
* @return <code>true</code>if identical otherwise <code>false</code>
*/
private boolean compareValues(Object value1, Object value2) {
boolean result = false;
if ((value1 == null) && (value2 == null)) {
return !result;
}
if ((value1 != null) && value1.equals(value2)) {
return !result;
}
return result;
}
/**
* Creates the Objects to edit the dynamic columns.<p>
*
* @param value the current value
* @param uploadFolder the upload folder path
* @param editable indicates if the entry can be edited by the current user
*
* @return the Object contains the current value and the widget to edit
*/
private CmsFormDataEditBean createEditEntry(String value, String uploadFolder, boolean editable) {
I_CmsWidget widget;
if (!uploadFolder.equals(WEBFORM_UPLOADFOLDER_NONE) && (value != null) && value.startsWith(uploadFolder)) {
widget = new CmsFormFileWidget();
} else if (!editable) {
widget = new CmsDisplayWidget();
// escape the value to ensure that no HTML code is executed
value = CmsEncoder.escapeXml(value);
} else if (isTextareaWidget(value)) {
widget = new CmsTextareaWidget(5);
} else {
widget = new CmsInputWidget();
}
return new CmsFormDataEditBean(value, widget);
}
/**
* Checks if the given String value is needed a textarea or a normal input field.<p>
*
* @param value the value to check if a textarea widget needed
*
* @return <code>true</code>if a textarea widget is needed otherwise <code>false</code>
*/
private boolean isTextareaWidget(String value) {
boolean result = false;
if (value != null) {
String escape = CmsStringUtil.escapeHtml(value);
boolean length = (value.length() > STRING_TRIM_SIZE);
length &= escape.matches(".*(<.{1,5}>|[ \\t\\n\\x0B\\f\\r]).*");
Pattern pat = Pattern.compile(".*(<.{1,5}>|[\\t\\n\\x0B\\f\\r]).*", Pattern.DOTALL);
Matcher match = pat.matcher(escape);
result = (length || match.matches());
}
return result;
}
}