/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.v8.excelimport/src/com/alkacon/opencms/v8/excelimport/CmsExcelImport.java,v $
* Date : $Date: 2011/02/24 15:33:36 $
* Version: $Revision: 1.3 $
*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (C) 2002 - 2009 Alkacon Software (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.alkacon.opencms.v8.excelimport;
import org.opencms.db.CmsPublishList;
import org.opencms.db.CmsResourceState;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.types.CmsResourceTypeXmlContent;
import org.opencms.loader.CmsLoaderException;
import org.opencms.lock.CmsLock;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.module.CmsModule;
import org.opencms.report.A_CmsReportThread;
import org.opencms.report.I_CmsReport;
import org.opencms.util.CmsStringUtil;
import org.opencms.workplace.CmsWorkplace;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.opencms.xml.types.CmsXmlDateTimeValue;
import org.opencms.xml.types.CmsXmlHtmlValue;
import org.opencms.xml.types.I_CmsXmlContentValue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
/**
* Imports an excel file and creates XML contents. Therefore the configuration file for import is located an validated.
* It is checked if an existing XML content belongs to an excel record. If yes, so this XML content is updated if
* excel record changed. Otherwise a new XML content is created.<p>
*
* @author Mario Jaeger
*
* @version $Revision: 1.3 $
*
* @since 7.5.0
*/
public class CmsExcelImport extends A_CmsReportThread {
/** The name of the current name.*/
public static final String MODULE_NAME = "com.alkacon.opencms.v8.excelimport";
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsExcelImport.class);
/** The upload object. */
private CmsResourceExcelImport m_cmsImport;
/** The interface to get additional configuration values. */
private I_CmsVfsSettings m_configParas;
/** The number of empty records. */
private int m_emptyRecords;
/** The number of not successful imported records. */
private int m_errImportedRecords;
/** The number of not successful updated records. */
private int m_errUpdatedRecords;
/** The list with found resources to excel file. */
private List m_foundResources = new ArrayList();
/** The number of successful imported records. */
private int m_importedRecords;
/** True, if there was an initialization error, otherwise false. */
private boolean m_initError;
/** The number of invalid records. */
private int m_invalidRecords;
/** The locale. */
private Locale m_locale;
/** The resources to publish.*/
private List m_publishList = new ArrayList();
/** The number of unchanged records. */
private int m_unchangedRecords;
/** The number of successful updated records. */
private int m_updatedRecords;
/**
* Constructor: Creates an import excel file thread.<p>
*
* @param cmsObject the current CmsObject action element
* @param cmsImport the import object
*/
public CmsExcelImport(CmsObject cmsObject, CmsResourceExcelImport cmsImport) {
super(cmsObject, "");
initHtmlReport(getCms().getRequestContext().getLocale());
m_cmsImport = cmsImport;
}
/**
* Gets dialog text for security dialog. This dialog can become made on/off with module parameter.
* It includes informations about errors in configurations and actions which will become executed.<p>
*
* @return dialog text content for security dialog
*/
public String getDialogText() {
StringBuffer buffer = new StringBuffer(4096);
Locale locale = getCms().getRequestContext().getLocale();
// configuration path
buffer.append(Messages.get().container(Messages.LOG_CONFIG_PATH_1, getPathFromConfigurationFiles()).key(locale)
+ "<br>");
// excel name
buffer.append(Messages.get().container(Messages.LOG_EXCEL_NAME_1, m_cmsImport.getExcelName()).key(locale)
+ "<br>");
// check configuration path
if (!checkConfigPath(getPathFromConfigurationFiles())) {
// invalid config path
buffer.append(Messages.get().container(Messages.LOG_ERR_INVALID_CONFIGPATH_0).key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// read excel file
CmsExcelContent cmsExcelContent = new CmsExcelContent();
cmsExcelContent.readExcelFile(getCms(), m_cmsImport.getExcelName(), m_cmsImport.getParamExcelContent());
if ((cmsExcelContent.getNumberOfRecords() > 0)
&& (CmsStringUtil.isNotEmpty(cmsExcelContent.getCategoryProperty()))) {
// excel properties
buffer.append(Messages.get().container(
Messages.LOG_EXCEL_CATEGORY_PROPERTY_1,
cmsExcelContent.getCategoryProperty()).key(locale)
+ "<br>");
buffer.append(Messages.get().container(
Messages.LOG_EXCEL_FOLDER_PROPERTY_1,
cmsExcelContent.getFolderProperty()).key(locale)
+ "<br>");
} else {
// empty excel file
buffer.append(Messages.get().container(Messages.LOG_ERR_EMPTY_EXCEL_1, "").key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// get configuration file to excel file
CmsExcelXmlConfiguration cmsExcelXmlConfiguration = getConfigurationFileToExcelFile(cmsExcelContent);
if (cmsExcelXmlConfiguration != null) {
buffer.append(Messages.get().container(
Messages.LOG_CONFIG_NAME_1,
cmsExcelXmlConfiguration.getConfigFileName()).key(locale)
+ "<br>");
} else {
// no configuration file
buffer.append(Messages.get().container(Messages.LOG_ERR_NO_CONFIGFILE_0, "").key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// check for valid configuration file
boolean validConfig = isValidConfiguration(cmsExcelXmlConfiguration);
if (!validConfig) {
// invalid configuration file
buffer.append(Messages.get().container(Messages.LOG_INVALID_CONFIGFILE_1, "").key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// check for valid excel file, all mandatory rows must be available
boolean validExcel = isValidExcel(cmsExcelContent, cmsExcelXmlConfiguration);
if (!validExcel) {
// invalid excel file
buffer.append(Messages.get().container(Messages.LOG_INVALID_EXCELFILE_1, "").key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// get path to handle existing XML contents in
String interfaceName = cmsExcelXmlConfiguration.getInterfaceName();
try {
if (CmsStringUtil.isNotEmpty(interfaceName)) {
m_configParas = getObject(interfaceName);
} else {
m_configParas = new CmsDefaultVfsSettings();
}
} catch (Exception e) {
// no interface
buffer.append(Messages.get().container(Messages.LOG_NO_INTERFACE_1, "").key(locale) + "<br><br>");
buffer.append(Messages.get().container(Messages.GUI_DIALOG_FAIL_QUESTION_0).key(locale));
return buffer.toString();
}
// get dialog text from interface
buffer.append(getDialogText(
getCms(),
m_cmsImport.getFolder(),
m_cmsImport.getExcelName(),
cmsExcelXmlConfiguration.getResourceType(),
m_cmsImport.getPublish(),
cmsExcelContent));
return buffer.toString();
}
/**
* @see org.opencms.report.A_CmsReportThread#getReportUpdate()
*/
public String getReportUpdate() {
return getReport().getReportUpdate();
}
/**
* Checks for valid settings in excel file and configuration file. It is proved if excel file is not
* empty and if there is set the excel property with OpenCms resource type. It is also proved
* if in configuration file is set a resource type and if there is at least one mapping.<p>
*
* @return true, if valid settings, otherwise false.
*/
public boolean isValid() {
// check config path
if (!checkConfigPath(getPathFromConfigurationFiles())) {
// invalid config path
return false;
}
// read excel file
CmsExcelContent cmsExcelContent = new CmsExcelContent();
cmsExcelContent.readExcelFile(getCms(), m_cmsImport.getExcelName(), m_cmsImport.getParamExcelContent());
if (!((cmsExcelContent.getNumberOfRecords() > 0) && (CmsStringUtil.isNotEmpty(cmsExcelContent.getCategoryProperty())))) {
// empty excel file
return false;
}
// get configuration file to excel file
CmsExcelXmlConfiguration cmsExcelXmlConfiguration = getConfigurationFileToExcelFile(cmsExcelContent);
if (cmsExcelXmlConfiguration == null) {
// no configuration file
return false;
}
// check for valid configuration file
boolean validConfig = isValidConfiguration(cmsExcelXmlConfiguration);
if (!validConfig) {
// invalid configuration file
return false;
}
// check for valid excel file, all mandatory rows must be available
boolean validExcel = isValidExcel(cmsExcelContent, cmsExcelXmlConfiguration);
if (!validExcel) {
// invalid excel file
return false;
}
// get path to handle existing XML contents in
String interfaceName = cmsExcelXmlConfiguration.getInterfaceName();
try {
if (CmsStringUtil.isNotEmpty(interfaceName)) {
m_configParas = getObject(interfaceName);
} else {
m_configParas = new CmsDefaultVfsSettings();
}
} catch (Exception e) {
// get dialog text from interface
return false;
}
// no interface
return true;
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
I_CmsReport report = getReport();
report.println(Messages.get().container(Messages.LOG_START_THREAD_EXCELIMPORT_0), I_CmsReport.FORMAT_HEADLINE);
if ((getCms() != null) && (m_cmsImport != null)) {
// read current user project
CmsProject currentProject = getCms().getRequestContext().currentProject();
try {
// sets import project
setProject(report, currentProject);
// import excel file
importExcelFile(report);
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
} finally {
// switch back to user project
getCms().getRequestContext().setCurrentProject(currentProject);
}
} else {
report.println(Messages.get().container(Messages.LOG_UPLOAD_FAILED_0), I_CmsReport.FORMAT_ERROR);
}
// report status
report.println();
report.print(
Messages.get().container(Messages.LOG_STATUS_0, new Integer(m_unchangedRecords)),
I_CmsReport.FORMAT_NOTE);
if ((m_errImportedRecords > 0) || (m_errUpdatedRecords > 0) || (m_invalidRecords > 0) || m_initError) {
// failed
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
} else {
// success
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
}
report.println();
report.println(Messages.get().container(Messages.LOG_END_THREAD_EXCELIMPORT_0), I_CmsReport.FORMAT_HEADLINE);
}
/**
* Check if configuration path is valid in OpenCms.<p>
*
* @param configPath configuration path
*
* @return true, if configuration path exists, otherwise false.
*/
private boolean checkConfigPath(String configPath) {
try {
// try to read path in OpenCms
getCms().readFolder(configPath);
} catch (CmsException e) {
// there was an error, so the path does not exist in OpenCms
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
return true;
}
/**
* Checks if excel record belongs to any existing XML content.
* For every excel record is looped over all existing XML contents
* and it is checked if excel record belongs to any from them.
* Excel record can only belong to one existing XML content. After
* the first match the prove for this excel record is canceled.<p>
*
* @param allXmlContents list with all existing XML contents
* @param cmsExcelContent excel content
* @param cmsExcelXmlConfiguration configuration content
* @param pathXmlContents path to XML contents
* @param recordCounter current excel record number
* @param report report for user
*
* @return true, if existing XML content was found, otherwise false
*/
private boolean checkExcelRecordAgainstAllXmlContents(
List allXmlContents,
CmsExcelContent cmsExcelContent,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
String pathXmlContents,
int recordCounter,
I_CmsReport report) {
int rowsToevaluate = getNumberOfColumnsToEvaluate(cmsExcelContent, cmsExcelXmlConfiguration);
Map currentRecord = cmsExcelContent.getRecord(recordCounter);
if (allXmlContents != null) {
// loop over all existing XML contents
Iterator iterXmlContents = allXmlContents.iterator();
while (iterXmlContents.hasNext()) {
CmsResource cmsResource = (CmsResource)iterXmlContents.next();
// resource did not change already in this import
if (!m_foundResources.contains(cmsResource.getResourceId().getStringValue())) {
boolean isXml = false;
try {
isXml = CmsResourceTypeXmlContent.isXmlContent(cmsResource);
} catch (Exception e) {
// no XML content
}
if (isXml) {
try {
CmsFile cmsFile = getCms().readFile(cmsResource);
CmsXmlContent xmlContent = CmsXmlContentFactory.unmarshal(getCms(), cmsFile);
// check current excel record against one XML content
boolean xmlContentFound = checkExcelRecordAgainstSingleXmlContent(
cmsResource,
cmsFile,
xmlContent,
cmsExcelContent,
pathXmlContents,
recordCounter,
cmsExcelXmlConfiguration,
currentRecord,
rowsToevaluate,
report);
if (xmlContentFound) {
// excel record is in existing XML content
m_foundResources.add(cmsResource.getResourceId().getStringValue());
return true;
}
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
} catch (RuntimeException e) {
// to catch "could not unmarshal XML content"
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
}
}
}
}
}
return false;
}
/**
* Check single excel record against single XML content. This methode includes logic
* to prove if excel record is in existing XML content included already.<p>
* If all column contents are the same in the mapped XML content, so the excel record
* is unchanged and nothing is to do with the XML content.<p>
* Every mapped column in excel record has a weight. All weights belongin to all unchanged
* column contents are added. If the sum from this weights is higher or equal than another
* configured weight, so the excel record belongs to this XML content, but changed.
* In this case the XML content is updated with the excel column values.<p>
* If the sum of weight from unchanged fields is lower than the other configured weight
* than the excel record does not belong to this XML content.<p>
*
* @param cmsResource current CmsResource
* @param cmsFile current CmsFile
* @param xmlContent current XML content
* @param currentRecord current record data as map
* @param cmsExcelContent excel object
* @param pathXmlContents path to XML contents
* @param numberExcelColumn number of excel columns
* @param cmsExcelXmlConfiguration configuration object
* @param rowsToevaluate number of rows in excel to evaluate
* @param report report object
*
* @return true, if existing XML content to excel record was found, otherwise false.
*/
private boolean checkExcelRecordAgainstSingleXmlContent(
CmsResource cmsResource,
CmsFile cmsFile,
CmsXmlContent xmlContent,
CmsExcelContent cmsExcelContent,
String pathXmlContents,
int numberExcelColumn,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
Map currentRecord,
int rowsToevaluate,
I_CmsReport report) {
CmsXmlContent xmlContentCopy = null;
try {
xmlContentCopy = CmsXmlContentFactory.unmarshal(getCms(), cmsFile);
} catch (CmsException e) {
// do nothing, because the original XML content exists, so this error should not happen...
}
// sum of weight for not changed fields
int notChangedWeight = 0;
// number of fields with unchanged fields
int numberSameContent = 0;
// loop over all columns from row
Iterator iterCol = currentRecord.keySet().iterator();
while (iterCol.hasNext()) {
// get user row name
String userColName = (String)iterCol.next();
if (CmsStringUtil.isNotEmpty(userColName)) {
// get XML tag name
String xmlTagName = cmsExcelXmlConfiguration.getXmlTagNameToExcelColumnName(userColName);
if (CmsStringUtil.isNotEmpty(xmlTagName)) {
// get XML content
try {
I_CmsXmlContentValue xmlTagContent = xmlContent.getValue(xmlTagName, m_locale);
// get excel content
String excelContent = (String)currentRecord.get(userColName);
if (CmsStringUtil.isEmpty(excelContent)) {
excelContent = "";
}
// get weight
int weight = cmsExcelXmlConfiguration.getWeightToExcelColumnName(userColName);
if ((xmlTagContent != null) && (xmlContentCopy != null)) {
String xmlTagContentValue = xmlTagContent.getStringValue(getCms());
// use a XML tag content copy to get value after setting in XML content
I_CmsXmlContentValue xmlTagContentCopy = xmlContentCopy.getValue(xmlTagName, m_locale);
xmlTagContentCopy.setStringValue(getCms(), excelContent);
String xmlTagContentCopyValue = xmlTagContentCopy.getStringValue(getCms());
// default value for XML tag to prove if empty excel column
String xmlTagContentCopyValueDefault = xmlTagContentCopy.getDefault(m_locale);
// compare excel content and XML tag content
if (xmlTagContentValue.equals(xmlTagContentCopyValue)) {
// excel content and XML tag content is same
notChangedWeight += weight;
numberSameContent += 1;
} else if (CmsStringUtil.isEmpty(excelContent)
&& (xmlTagContentValue.equals(xmlTagContentCopyValueDefault))) {
// empty excel content, is default value set in XML content so it is also the same
notChangedWeight += weight;
numberSameContent += 1;
} else if (CmsStringUtil.isEmpty(excelContent) && xmlTagContentValue.equals("(none)")) {
// select box with no selected value after user changed XML content
notChangedWeight += weight;
numberSameContent += 1;
} else {
// prove for data type CmsHtml
if (xmlContent.getContentDefinition().getSchemaType(xmlTagName).getTypeName().equals(
CmsXmlHtmlValue.TYPE_NAME)
&& xmlTagContentValue.startsWith("<p>")
&& xmlTagContentValue.endsWith("</p>")) {
String valueWithoutHtml = xmlTagContentValue.substring(
3,
xmlTagContentValue.length() - 4);
if (valueWithoutHtml.equals(excelContent)) {
// after user changed XML content, filled CmsXmlHtmlValues can become surrounded with html <p> tags
notChangedWeight += weight;
numberSameContent += 1;
}
} else if (CmsStringUtil.isEmpty(excelContent)
&& xmlContent.getContentDefinition().getSchemaType(xmlTagName).getTypeName().equals(
CmsXmlHtmlValue.TYPE_NAME)
&& xmlTagContentValue.equals("<br />")) {
// after user changed XML content, empty CmsXmlHtmlValues can be <br /> tag
notChangedWeight += weight;
numberSameContent += 1;
}
}
} else if ((xmlTagContent == null) && CmsStringUtil.isEmpty(excelContent)) {
// empty excel content and optional tag is disabled, so it is the same
notChangedWeight += weight;
numberSameContent += 1;
}
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
}
}
}
// evaluation
if (numberSameContent == rowsToevaluate) {
// not changed record ---> do nothing
report.print(
Messages.get().container(
Messages.LOG_UNCHANGED_XML_2,
new Integer(numberExcelColumn + 1).toString(),
getCms().getSitePath(cmsFile)),
I_CmsReport.FORMAT_NOTE);
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
m_unchangedRecords += 1;
return true;
} else if (notChangedWeight >= cmsExcelXmlConfiguration.getMinWeight()) {
// changed record, so update it
report.print(
Messages.get().container(
Messages.LOG_UPDATE_XML_2,
new Integer(numberExcelColumn + 1).toString(),
getCms().getSitePath(cmsFile)),
I_CmsReport.FORMAT_NOTE);
//lock file
boolean locked = false;
try {
locked = lockResource(cmsFile);
} catch (CmsException e) {
report.print(Messages.get().container(Messages.LOG_ERR_NO_LOCK_0), I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_errUpdatedRecords += 1;
return true;
}
// locking file was successful
if (locked) {
// update XML content
if (setValuesInXmlContent(
cmsResource,
cmsFile,
xmlContent,
currentRecord,
cmsExcelXmlConfiguration,
true,
report)) {
// updating XML content was successful
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
m_updatedRecords += 1;
} else {
// updating XML content failed
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_errUpdatedRecords += 1;
}
return true;
} else {
// locking resource failed
report.print(Messages.get().container(Messages.LOG_ERR_NO_LOCK_0), I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_errUpdatedRecords += 1;
return true;
}
} else {
// XML content is too different from excel content
return false;
}
}
/**
* Creates a new XML content from given OpenCms resource type and contents from current excel record.<p>
*
* @param pathXmlContents path to XML contents
* @param resourceType resource type to create
* @param newFileName new filename
* @param currentRecord current record from excel
* @param cmsExcelXmlConfiguration configuration
* @param report report
*
* @return true, if creating new XML content was successful, otherwise false.
*/
private boolean createNewXmlContentFile(
String pathXmlContents,
String resourceType,
String newFileName,
Map currentRecord,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
I_CmsReport report) {
int resourceTypeInt = 0;
try {
resourceTypeInt = OpenCms.getResourceManager().getResourceType(resourceType).getTypeId();
} catch (CmsLoaderException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
String completeNewFileName = "";
if (resourceTypeInt > 0) {
try {
completeNewFileName = pathXmlContents.concat(newFileName);
getCms().createResource(completeNewFileName, resourceTypeInt);
CmsFile cmsFile = getCms().readFile(completeNewFileName);
CmsResource cmsResource = getCms().readResource(completeNewFileName);
CmsXmlContent xmlContent = CmsXmlContentFactory.unmarshal(getCms(), cmsFile);
// set values from excel file into file
if (setValuesInXmlContent(
cmsResource,
cmsFile,
xmlContent,
currentRecord,
cmsExcelXmlConfiguration,
false,
report)) {
return true;
} else {
getCms().deleteResource(completeNewFileName, CmsResource.DELETE_PRESERVE_SIBLINGS);
}
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
}
return false;
}
/**
* In this method is looped over all excel records and it is proved if an excel record
* belongs to an existing XML content. If an excel record does not belong to an existing
* XML content so a new XML content is created.<p>
*
* @param cmsExcelContent excel content object
* @param cmsExcelXmlConfiguration configuration object
* @param pathXmlContents path to XML contents
* @param report report object
*/
private void evaluateExcelRecords(
CmsExcelContent cmsExcelContent,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
String pathXmlContents,
I_CmsReport report) {
// read all existing XML contents
List allXmlContents = null;
try {
allXmlContents = getCms().readResources(pathXmlContents, CmsResourceFilter.IGNORE_EXPIRATION, false);
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
}
// loop over all excel records
for (int recordCounter = 1; recordCounter <= cmsExcelContent.getNumberOfRecords(); recordCounter++) {
// check for not empty excel record
boolean emptyRecord = cmsExcelContent.isEmptyRecord(recordCounter);
if (emptyRecord) {
m_emptyRecords += 1;
} else {
// check for valid excel content -> all mandatory fields have to become filled
boolean validExcelRecord = isValidExcelRecord(cmsExcelContent, cmsExcelXmlConfiguration, recordCounter);
if (validExcelRecord) {
// loop over all existing XML contents if there exists a XML content belonging to current excel record
boolean xmlContentFound = checkExcelRecordAgainstAllXmlContents(
allXmlContents,
cmsExcelContent,
cmsExcelXmlConfiguration,
pathXmlContents,
recordCounter,
report);
if (!xmlContentFound) {
// no existing XML content found -> create new XML content
String newFileName = m_configParas.getNewFileName(
getCms(),
m_cmsImport.getFolder(),
cmsExcelXmlConfiguration.getResourceType(),
cmsExcelContent);
// output to the report
report.print(
Messages.get().container(
Messages.LOG_CREATE_XML_2,
String.valueOf(recordCounter + 1),
pathXmlContents.concat(newFileName)),
I_CmsReport.FORMAT_NOTE);
// create new XML content
if (createNewXmlContentFile(
pathXmlContents,
cmsExcelXmlConfiguration.getResourceType(),
newFileName,
cmsExcelContent.getRecord(recordCounter),
cmsExcelXmlConfiguration,
report)) {
// creating XML content was successful
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
m_importedRecords += 1;
} else {
// creating resource failed
report.println(
Messages.get().container(Messages.LOG_ERR_FAILED_0),
I_CmsReport.FORMAT_ERROR);
m_errImportedRecords += 1;
}
}
} else {
// invalid excel record
report.print(
Messages.get().container(Messages.LOG_INVALID_EXCEL_RECORD_1, String.valueOf(recordCounter + 1)),
I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_invalidRecords += 1;
}
}
}
}
/**
* Gets configuration file belonging to excel file. The mapping between excel file and configuration
* file is between a property from excel file and a setting in configuration file in form from OpenCms
* resource type name.<p>
*
* @param cmsExcelContent content from excel file
* @param report report content for user
*
* @return configuration file content belonging to excel file
*/
private CmsExcelXmlConfiguration getConfigurationFileToExcelFile(CmsExcelContent cmsExcelContent) {
CmsExcelXmlConfiguration cmsExcelXmlConfiguration = null;
// get property content for resource type
String excelProperty = cmsExcelContent.getCategoryProperty();
if (CmsStringUtil.isNotEmpty(excelProperty)) {
// get path to configuration files
String configFilesPath = getPathFromConfigurationFiles();
if (configFilesPath != null) {
try {
// get all configuration files
List allConfigFiles = getCms().readResources(configFilesPath, CmsResourceFilter.ALL, false);
if (allConfigFiles != null) {
// loop over all existing configuration files
Iterator iter = allConfigFiles.iterator();
while (iter.hasNext()) {
// get next configuration file
CmsResource cmsResource = (CmsResource)iter.next();
cmsExcelXmlConfiguration = new CmsExcelXmlConfiguration();
// read configuration file
cmsExcelXmlConfiguration.readConfigurationFile(getCms(), getCms().getSitePath(cmsResource));
// prove if setting from OpenCms resource type in excel file is the same like in the
// configuration file
if (CmsStringUtil.isNotEmpty(cmsExcelXmlConfiguration.getResourceType())
&& cmsExcelXmlConfiguration.getResourceType().equals(excelProperty)) {
// if a belonging configuration file is found, the configuration file is returned
return cmsExcelXmlConfiguration;
}
}
}
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
}
}
}
return null;
}
/**
* Gets the dialog text for security dialog, which is configurable in module parameters.
* This method includes informations about the actions which will become executed, for
* example the excel file name, the path where XML contents are created or updated.<p>
*
* @param cmsObject current CmsObject
* @param workplacePath current path in workplace
* @param excelName name from excel file
* @param resourceType selected resource type
* @param publish true, if resources shall become published, otherwise false
* @param cmsExcelContent the excel content
*
* @return the dialog text for security dialog
*/
private String getDialogText(
CmsObject cmsObject,
String workplacePath,
String excelName,
String resourceType,
boolean publish,
CmsExcelContent cmsExcelContent) {
StringBuffer buffer = new StringBuffer(4096);
// here choose user locale and not workplace directory locale
Locale locale = getCms().getRequestContext().getLocale();
// excel name
buffer.append(Messages.get().container(Messages.GUI_DIALOG_EXCEL_NAME_1, excelName).key(locale) + "<br>");
// info where new resources are created and where resources are updated
buffer.append(Messages.get().container(
Messages.GUI_DIALOG_ACTION_2,
resourceType,
m_configParas.getPathToXmlContents(cmsObject, workplacePath, resourceType, cmsExcelContent)).key(locale)
+ "<br>");
// publish info
if (publish) {
buffer.append(Messages.get().container(Messages.LOG_PUBLISH_0).key(locale) + "<br><br>");
} else {
buffer.append(Messages.get().container(Messages.LOG_NOT_PUBLISH_0).key(locale) + "<br><br>");
}
// Okay to start message
buffer.append(Messages.get().container(Messages.GUI_DIALOG_SUCC_QUESTION_0).key(locale));
return buffer.toString();
}
/**
* Gets number of columns in excel file to evaluate.<p>
*
* @param cmsExcelContent current excel content
* @param cmsExcelXmlConfiguration current configuration
*
* @return number of columns in excel file to evaluate
*/
private int getNumberOfColumnsToEvaluate(
CmsExcelContent cmsExcelContent,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration) {
int rows = 0;
// all excel user column names
Map excelRowNames = cmsExcelContent.getColumnNames();
// loop over all excel column names
Iterator iter = excelRowNames.keySet().iterator();
while (iter.hasNext()) {
String userRowName = (String)iter.next();
// get XML tag name from config file to excel user column name
String xmlTagName = cmsExcelXmlConfiguration.getXmlTagNameToExcelColumnName(userRowName);
// if there is a XML tag name so this excel user column name must become evaluated
if (CmsStringUtil.isNotEmpty(xmlTagName)) {
rows += 1;
}
}
return rows;
}
/**
* Creates an object from data type I_CmsConfigurationParameters.
* This is necessary for the interface which can become used in configuration file.<p>
*
* @param className name from class to create an object from
*
* @return object from data type I_CmsConfigurationParameters
*/
private I_CmsVfsSettings getObject(String className) throws Exception {
I_CmsVfsSettings object = null;
Class c = Class.forName(className);
object = (I_CmsVfsSettings)c.newInstance();
return object;
}
/**
* Returns the path of configuration files from the module parameter.<p>
*
* @return the path of configuration files from the module parameter
*/
private String getPathFromConfigurationFiles() {
String path = "";
// get the module
CmsModule module = OpenCms.getModuleManager().getModule(MODULE_NAME);
if (module != null) {
path = module.getParameter("configurationpath", CmsWorkplace.VFS_PATH_MODULES
+ MODULE_NAME
+ "/configurations/");
}
return path;
}
/**
* Returns the project name which shall become used for excel import. Project is configurable
* in module parameter.<p>
*
* @return the project name which shall become used for excel import
*/
private String getUploadProject() {
String path = "";
// get the module
CmsModule module = OpenCms.getModuleManager().getModule(MODULE_NAME);
if (module != null) {
path = module.getParameter("uploadproject");
if (path == null) {
path = "";
}
}
return path;
}
/**
* Here the excel file import starts.. Before start is proved if all configurations in excel file are correct. It
* is proved if there is a configuration file belonging to excel file. It is proved if configuration file settings are
* correct. Only if settings are correct, the import from excel file can become started. After importing
* the publishing from changed or new created resources is executed, if necessary.<p>
*
* @param report report for user
*/
private void importExcelFile(I_CmsReport report) {
// check configuration path
report.print(
Messages.get().container(Messages.LOG_CONFIG_PATH_1, getPathFromConfigurationFiles()),
I_CmsReport.FORMAT_NOTE);
if (checkConfigPath(getPathFromConfigurationFiles())) {
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
} else {
// invalid configuration path
report.print(Messages.get().container(Messages.LOG_ERR_INVALID_CONFIGPATH_0), I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
return;
}
// read excel file
report.println(
Messages.get().container(Messages.LOG_EXCEL_NAME_1, m_cmsImport.getExcelName()),
I_CmsReport.FORMAT_NOTE);
CmsExcelContent cmsExcelContent = new CmsExcelContent();
cmsExcelContent.readExcelFile(getCms(), m_cmsImport.getExcelName(), m_cmsImport.getParamExcelContent());
if ((cmsExcelContent.getNumberOfRecords() > 0)
&& (CmsStringUtil.isNotEmpty(cmsExcelContent.getCategoryProperty()))) {
// excel properties
report.println(
Messages.get().container(Messages.LOG_EXCEL_CATEGORY_PROPERTY_1, cmsExcelContent.getCategoryProperty()),
I_CmsReport.FORMAT_NOTE);
report.println(
Messages.get().container(Messages.LOG_EXCEL_FOLDER_PROPERTY_1, cmsExcelContent.getFolderProperty()),
I_CmsReport.FORMAT_NOTE);
} else {
// empty excel file
report.print(
Messages.get().container(Messages.LOG_ERR_EMPTY_EXCEL_1, m_cmsImport.getExcelName()),
I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_initError = true;
return;
}
// get configuration file to excel file
CmsExcelXmlConfiguration cmsExcelXmlConfiguration = getConfigurationFileToExcelFile(cmsExcelContent);
if (cmsExcelXmlConfiguration != null) {
report.println(
Messages.get().container(Messages.LOG_CONFIG_NAME_1, cmsExcelXmlConfiguration.getConfigFileName()),
I_CmsReport.FORMAT_NOTE);
} else {
// no configuration file
report.print(Messages.get().container(Messages.LOG_ERR_NO_CONFIGFILE_0, ""), I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_initError = true;
return;
}
// check for valid configuration file
boolean validConfig = isValidConfiguration(cmsExcelXmlConfiguration);
if (!validConfig) {
// invalid configuration file
report.print(
Messages.get().container(
Messages.LOG_INVALID_CONFIGFILE_1,
cmsExcelXmlConfiguration.getConfigFileName()),
I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_initError = true;
return;
}
// check for valid excel file, all mandatory rows must be available
boolean validExcel = isValidExcel(cmsExcelContent, cmsExcelXmlConfiguration);
if (!validExcel) {
// invalid excel file
report.print(
Messages.get().container(Messages.LOG_INVALID_EXCELFILE_1, cmsExcelContent.getExcelName()),
I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_initError = true;
return;
}
// get path to handle existing XML contents in
String interfaceName = cmsExcelXmlConfiguration.getInterfaceName();
try {
if (CmsStringUtil.isNotEmpty(interfaceName)) {
m_configParas = getObject(interfaceName);
} else {
m_configParas = new CmsDefaultVfsSettings();
}
} catch (Exception e) {
// no interface
report.print(Messages.get().container(Messages.LOG_NO_INTERFACE_1, interfaceName), I_CmsReport.FORMAT_NOTE);
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
m_initError = true;
return;
}
String pathXmlContents = m_configParas.getPathToXmlContents(
getCms(),
m_cmsImport.getFolder(),
cmsExcelXmlConfiguration.getResourceType(),
cmsExcelContent);
m_locale = OpenCms.getLocaleManager().getDefaultLocale(getCms(), pathXmlContents);
// check path to import the xml contents in
if (!getCms().existsResource(pathXmlContents)) {
// could not read the path
report.println(
Messages.get().container(Messages.LOG_EXCEL_IMPORT_PATH_NOT_FOUND_1, pathXmlContents),
I_CmsReport.FORMAT_ERROR);
return;
}
// evaluate excel contents
report.println();
report.println(Messages.get().container(Messages.LOG_START_EXCELIMPORT_0, ""), I_CmsReport.FORMAT_NOTE);
evaluateExcelRecords(cmsExcelContent, cmsExcelXmlConfiguration, pathXmlContents, report);
report.println(Messages.get().container(Messages.LOG_END_EXCELIMPORT_0, ""), I_CmsReport.FORMAT_NOTE);
// publish resources
if (m_cmsImport.getPublish()) {
publish(report);
}
// write import status to report
reportImportStatus(report, cmsExcelContent.getNumberOfRecords());
}
/**
* Checks configuration file is valid. It is checked if there is at least one mapping set in this file.<p>
*
* @param cmsExcelXmlConfiguration Configuration content
*
* @return true, if configuration file is valid, otherwise false
*/
private boolean isValidConfiguration(CmsExcelXmlConfiguration cmsExcelXmlConfiguration) {
// at least one mapping must become set
List mappings = cmsExcelXmlConfiguration.getMappings();
if (mappings.size() < 1) {
return false;
}
return true;
}
/**
* Checks excel file is valid. It is checked that file is not empty and that the property
* with OpenCms resource type is set.<p>
*
* @param cmsExcelContent excel content
* @param cmsExcelXmlConfiguration configuration content
*
* @return true, if excel file is valid, otherwise false
*/
private boolean isValidExcel(CmsExcelContent cmsExcelContent, CmsExcelXmlConfiguration cmsExcelXmlConfiguration) {
// list with all mandatory columns
List mandatoryCols = cmsExcelXmlConfiguration.getMandatoryUserColumnNames();
// list with available excel columns
Map userCols = cmsExcelContent.getColumnNames();
// prove that all mandatory columns are included in excel content
Iterator iter = mandatoryCols.iterator();
while (iter.hasNext()) {
String mandatoryCol = (String)iter.next();
boolean valid = userCols.containsKey(mandatoryCol);
if (!valid) {
return false;
}
}
return true;
}
/**
* Checks if excel record is valid. An excel record is valid if the mandatory column values are not empty.<p>
*
* @param cmsExcelContent Excel content
* @param cmsExcelXmlConfiguration Configuration content
* @param recordCounter Number of current excel record
*
* @return true, if excel file record is valid
*/
private boolean isValidExcelRecord(
CmsExcelContent cmsExcelContent,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
int recordCounter) {
// list with all mandatory rows
List mandatoryRows = cmsExcelXmlConfiguration.getMandatoryUserColumnNames();
// prove that to every mandatory row is a filled excel cell
Iterator iter = mandatoryRows.iterator();
while (iter.hasNext()) {
// get next mandatory column name
String mandatoryRow = (String)iter.next();
// get content from this column
String excelContent = cmsExcelContent.getCellContent(mandatoryRow, recordCounter);
if (CmsStringUtil.isEmpty(excelContent)) {
// mandatory column value is empty -> record is not valid
return false;
}
}
return true;
}
/**
* Locks the current resource.<p>
*
* @param cms the current CmsObject
* @param cmsFile the file to lock
* @param report the report
*
* @throws CmsException if some goes wrong
*/
private boolean lockResource(CmsFile cmsFile) throws CmsException {
CmsLock lock = getCms().getLock(getCms().getSitePath(cmsFile));
// check the lock
if ((lock != null)
&& lock.isOwnedBy(getCms().getRequestContext().currentUser())
&& lock.isOwnedInProjectBy(
getCms().getRequestContext().currentUser(),
getCms().getRequestContext().currentProject())) {
// prove is current lock from current user in current project
return true;
} else if ((lock != null) && !lock.isUnlocked() && !lock.isOwnedBy(getCms().getRequestContext().currentUser())) {
// the resource is not locked by the current user, so can not lock it
return false;
} else if ((lock != null)
&& !lock.isUnlocked()
&& lock.isOwnedBy(getCms().getRequestContext().currentUser())
&& !lock.isOwnedInProjectBy(
getCms().getRequestContext().currentUser(),
getCms().getRequestContext().currentProject())) {
// prove is current lock from current user but not in current project
// file is locked by current user but not in current project
// change the lock
getCms().changeLock(getCms().getSitePath(cmsFile));
} else if ((lock != null) && lock.isUnlocked()) {
// lock resource from current user in current project
getCms().lockResource(getCms().getSitePath(cmsFile));
}
lock = getCms().getLock(getCms().getSitePath(cmsFile));
if ((lock != null)
&& lock.isOwnedBy(getCms().getRequestContext().currentUser())
&& !lock.isOwnedInProjectBy(
getCms().getRequestContext().currentUser(),
getCms().getRequestContext().currentProject())) {
// resource could not be locked
return false;
}
// resource is locked successfully
return true;
}
/**
* Publish resources. All XML contents are published which are new created from this thread
* and which wre changed from this thread. All resources to publish are saved in a publish list.
* This list is become published here.<p>
*
* @param report report for user
*
*/
private void publish(I_CmsReport report) {
report.println();
report.print(Messages.get().container(Messages.LOG_RECORDS_PUBLISH_0), I_CmsReport.FORMAT_NOTE);
try {
// create OpenCms publish list with publish list from all new created and updated XML contents
CmsPublishList pubList = OpenCms.getPublishManager().getPublishList(getCms(), m_publishList, false);
OpenCms.getPublishManager().publishProject(getCms(), null, pubList);
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
report.println(Messages.get().container(Messages.LOG_ERR_FAILED_0), I_CmsReport.FORMAT_ERROR);
return;
}
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
}
/**
* Writes status from to report. Includes the output from number of number of excel records, the
* number of new created XML contents, from updated XML contents and from not changed XML contents.<p>
*
* @param report report for user
* @param records number of records to import
*/
private void reportImportStatus(I_CmsReport report, int records) {
report.println();
// records in excel
report.println(
Messages.get().container(Messages.LOG_RECORDS_IN_EXCEL_1, new Integer(records - m_emptyRecords)),
I_CmsReport.FORMAT_NOTE);
// invalid records
report.println(
Messages.get().container(Messages.LOG_INVALID_RECORDS_1, new Integer(m_invalidRecords)),
I_CmsReport.FORMAT_NOTE);
// successful imported records
report.println(
Messages.get().container(Messages.LOG_SUCC_IMPORTED_1, new Integer(m_importedRecords)),
I_CmsReport.FORMAT_NOTE);
// not successful imported records
report.println(
Messages.get().container(Messages.LOG_FAIL_IMPORTED_1, new Integer(m_errImportedRecords)),
I_CmsReport.FORMAT_NOTE);
// successful updated records
report.println(
Messages.get().container(Messages.LOG_SUCC_UPDATED_1, new Integer(m_updatedRecords)),
I_CmsReport.FORMAT_NOTE);
// not successful updated records
report.println(
Messages.get().container(Messages.LOG_FAIL_UPDATED_1, new Integer(m_errUpdatedRecords)),
I_CmsReport.FORMAT_NOTE);
// unchanged records
report.println(
Messages.get().container(Messages.LOG_UNCHANGED_1, new Integer(m_unchangedRecords)),
I_CmsReport.FORMAT_NOTE);
}
/**
* Sets import project. It is proved if project which is configured in module parameters is valid.
* If project can not become set so is used the current project from user for import.<p>
*
* @param report report for user
* @param currentProject Current project from user
*/
private void setProject(I_CmsReport report, CmsProject currentProject) {
String uploadProject = getUploadProject();
if (CmsStringUtil.isNotEmpty(uploadProject)) {
// use upload project
report.print(
Messages.get().container(Messages.LOG_UPLOAD_PROJECT_1, uploadProject),
I_CmsReport.FORMAT_NOTE);
try {
// try to set upload project as current project
CmsProject cmsUploadProject = getCms().readProject(uploadProject);
getCms().getRequestContext().setCurrentProject(cmsUploadProject);
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
} catch (CmsException e) {
// no valid upload project, so use current user project
getCms().getRequestContext().setCurrentProject(currentProject);
report.print(
Messages.get().container(Messages.LOG_ERR_UPLOAD_PROJECT_1, currentProject.getName()),
I_CmsReport.FORMAT_NOTE);
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
}
} else {
// use current user project
report.print(
Messages.get().container(Messages.LOG_NO_UPLOAD_PROJECT_1, currentProject.getName()),
I_CmsReport.FORMAT_NOTE);
report.println(
org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
I_CmsReport.FORMAT_OK);
}
}
/**
* Set values in a XML content. The values come from the current excel record.<p>
*
* @param cmsResource current CmsResource
* @param cmsFile current CmsFile
* @param xmlContent XML content
* @param currentRecord current excel record
* @param cmsExcelXmlConfiguration configuration
* @param provePublish prove if publish
* @param report report for user
*
* @return true, if setting values in XML content was successful, otherwise false
*/
private boolean setValuesInXmlContent(
CmsResource cmsResource,
CmsFile cmsFile,
CmsXmlContent xmlContent,
Map currentRecord,
CmsExcelXmlConfiguration cmsExcelXmlConfiguration,
boolean provePublish,
I_CmsReport report) {
// prove locale in XML content
boolean hasLocale = false;
// get all locales from XML content
List locales = xmlContent.getLocales();
// loop over all these locales
Iterator iterLocale = locales.iterator();
while (iterLocale.hasNext()) {
Locale localeXml = (Locale)iterLocale.next();
// prove current locale from XML content to locale from workplace directory
if (localeXml.getLanguage().equals(m_locale.getLanguage())) {
// locale from workplace directory is included in XML content, so use it
hasLocale = true;
}
}
// locale from workplace directory is not included in XML content, so take first locale from XML content
if (!hasLocale) {
try {
xmlContent.addLocale(getCms(), m_locale);
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
}
// get data from current excel record
Iterator iterRows = currentRecord.keySet().iterator();
while (iterRows.hasNext()) {
// get user row name
String userRowName = (String)iterRows.next();
if (CmsStringUtil.isNotEmpty(userRowName)) {
// get XML tag name
String xmlTagName = cmsExcelXmlConfiguration.getXmlTagNameToExcelColumnName(userRowName);
if (CmsStringUtil.isNotEmpty(xmlTagName)) {
try {
// get excel content
String excelContent = (String)currentRecord.get(userRowName);
boolean hasValue = xmlContent.hasValue(xmlTagName, m_locale);
// do nothing if excel content is empty and content has this tag
if (CmsStringUtil.isEmpty(excelContent) && !hasValue) {
// if empty excel content and tag is disabled do nothing
} else {
I_CmsXmlContentValue contentValue = null;
// if there is an optional nested content in XML tag, so this content must become created at first
// thats why the following operations are necessary
// split XML tag by slash
String[] elements = xmlTagName.split("/");
// full xPath is added step by step by single parts from XML tag
String fullXPath = "";
// loop over all parts from XML tag, which were splitted by slash
// for every part is to prove if tag is included in XML content already, if not so
// it must become created
for (int elementCounter = 0; elementCounter < elements.length; elementCounter++) {
if (fullXPath.isEmpty()) {
// fill xPath with the first element from XML tag
fullXPath = elements[elementCounter];
} else {
// fill xPath with next element from XML tag
fullXPath = fullXPath.concat("/" + elements[elementCounter]);
}
// prove if XML content included the xPath
if (!xmlContent.hasValue(fullXPath, m_locale)) {
// XML content still does not contain this xPath, so create it
contentValue = xmlContent.addValue(getCms(), fullXPath, m_locale, 0);
} else {
// XML content already does contain this xPath, so get it
contentValue = xmlContent.getValue(fullXPath, m_locale);
}
}
if (contentValue != null) {
if (CmsStringUtil.isEmpty(excelContent)) {
// empty excel content, so set default value
String defaultValue = contentValue.getDefault(m_locale);
if (CmsStringUtil.isEmpty(defaultValue)) {
defaultValue = "";
}
// date value, so the "0" is also empty
if (xmlContent.getContentDefinition().getSchemaType(xmlTagName).getTypeName().equals(
CmsXmlDateTimeValue.TYPE_NAME)
&& defaultValue.equals("0")
&& (contentValue.getMinOccurs() == 0)) {
xmlContent.removeValue(xmlTagName, m_locale, 0);
} else if (CmsStringUtil.isEmpty(defaultValue)
&& (contentValue.getMinOccurs() == 0)) {
xmlContent.removeValue(xmlTagName, m_locale, 0);
} else {
contentValue.setStringValue(getCms(), defaultValue);
}
} else {
// set excel content
contentValue.setStringValue(getCms(), excelContent);
}
}
}
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
report.print(
Messages.get().container(
Messages.LOG_ERR_INVALID_XMLTAG_1,
xmlTagName,
getCms().getSitePath(cmsFile)),
I_CmsReport.FORMAT_NOTE);
return false;
}
}
}
}
// write to file
if (writeToFile(xmlContent, cmsResource, cmsFile, provePublish)) {
return true;
}
return false;
}
/**
* Writes XML content to file. <p>
*
* @param xmlContent current XML content
* @param cmsResource current CmsResource
* @param cmsFile current file
* @param provePublish prove if publish resource
*
* @return true, if writing to file was successful, otherwise false
*/
private boolean writeToFile(CmsXmlContent xmlContent, CmsResource cmsResource, CmsFile cmsFile, boolean provePublish) {
try {
// set XML content to file
cmsFile.setContents(xmlContent.marshal());
// write file
cmsFile = getCms().writeFile(cmsFile);
// unlock file
CmsLock lock = getCms().getLock(getCms().getSitePath(cmsFile));
if (!lock.getType().isInherited()) {
getCms().unlockResource(getCms().getSitePath(cmsFile));
}
} catch (CmsException e) {
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
// if resources shall become published, so the resources come into the publish list
if (m_cmsImport.getPublish()) {
// get correct resource status
if (cmsResource.getState().equals(CmsResourceState.STATE_UNCHANGED)) {
try {
cmsResource = getCms().readResource(getCms().getSitePath(cmsResource));
} catch (CmsException e) {
// should not happen because resource exists
if (LOG.isErrorEnabled()) {
LOG.error(e);
}
return false;
}
}
// read resource again to have correct status
m_publishList.add(cmsFile);
}
return true;
}
}