blob: 94456f96f3343e690ba649b50a469c630c31ff9e [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.apache.ofbiz.birt.flexible;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.birt.BirtWorker;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.condition.EntityCondition;
import org.apache.ofbiz.entity.condition.EntityConditionList;
import org.apache.ofbiz.entity.condition.EntityExpr;
import org.apache.ofbiz.entity.condition.EntityOperator;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelField;
import org.apache.ofbiz.entity.util.EntityListIterator;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ModelService;
import org.apache.ofbiz.service.ServiceUtil;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.script.IReportContext;
import org.eclipse.birt.report.model.api.DesignConfig;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.DesignFileException;
import org.eclipse.birt.report.model.api.IDesignEngine;
import org.eclipse.birt.report.model.api.IDesignEngineFactory;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.SessionHandle;
import org.eclipse.birt.report.model.api.SimpleMasterPageHandle;
import org.eclipse.birt.report.model.api.SlotHandle;
import org.eclipse.birt.report.model.api.VariableElementHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.birt.report.model.elements.SimpleMasterPage;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.ibm.icu.util.ULocale;
/**
* Birt Services
*/
public class BirtServices {
public static final String module = BirtServices.class.getName();
public static final String resource = "BirtUiLabels";
public static final String resource_error = "BirtErrorUiLabels";
public static final String resourceProduct = "BirtUiLabels";
/**
* Instantiate a new Flexible report, using the data given in parameters and <code>ReportDesignGenerator</code> class.
*/
public static Map<String, Object> createFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
ReportDesignGenerator rptGenerator;
try {
rptGenerator = new ReportDesignGenerator(context, dctx);
} catch (Exception e1) {
e1.printStackTrace();
return ServiceUtil.returnError(e1.getMessage());
}
try {
rptGenerator.buildReport();
} catch (Exception e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess();
}
@Deprecated
public static Map<String, Object> prepareFlexibleReportOptionFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
String entityViewName = (String) context.get("entityViewName");
GenericValue userLogin = (GenericValue) context.get("userLogin");
List<String> listMultiFields = new ArrayList<String>();
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Map<String, Object> result = new HashMap<String, Object>();
Locale locale = (Locale) context.get("locale");
ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
List<String> listFieldsEntity = modelEntity.getAllFieldNames();
for (String field : listFieldsEntity) {
listMultiFields.add(field);
ModelField mField = modelEntity.getField(field);
String fieldType = mField.getType();
String birtType = null;
try {
Map<String, Object> convertRes = dispatcher.runSync("convertFieldTypeToBirtType", UtilMisc.toMap("fieldType", fieldType, "userLogin", userLogin));
birtType = (String) convertRes.get("birtType");
if (UtilValidate.isEmpty(birtType)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorConversionFieldToBirtFailed", locale));
}
} catch (GenericServiceException e) {
e.printStackTrace();
}
// make more general when report forms have been made so too.
if (birtType.equalsIgnoreCase("date-time") || birtType.equalsIgnoreCase("date") || birtType.equalsIgnoreCase("time")) {
listMultiFields.add(field + "_fld0_op");
listMultiFields.add(field + "_fld0_value");
listMultiFields.add(field + "_fld1_op");
listMultiFields.add(field + "_fld1_value");
}
}
result.put("listMultiFields", listMultiFields);
return result;
}
/**
* Perform find data on given view/entity and return these into birt compatible format.
* This service is meant to be used as default for View/entity report design
*
*/
public static Map<String, Object> callPerformFindFromBirt(DispatchContext dctx, Map<String, Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
IReportContext reportContext = (IReportContext) context.get("reportContext");
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
String entityViewName = (String) reportContext.getParameterValue("modelElementName");
Map<String, Object> inputFields = (Map<String, Object>) reportContext.getParameterValue("parameters");
Map<String, Object> resultPerformFind = new HashMap<String, Object>();
Map<String, Object> resultToBirt = null;
List<GenericValue> list = null;
if (UtilValidate.isEmpty(entityViewName)) {
entityViewName = (String) inputFields.get("modelElementName");
if (UtilValidate.isEmpty(entityViewName)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotFound", locale));
}
}
try {
resultPerformFind = dispatcher.runSync("performFind", UtilMisc.<String, Object>toMap("entityName", entityViewName, "inputFields", inputFields, "userLogin", userLogin, "noConditionFind", "Y", "locale", locale));
if (ServiceUtil.isError(resultPerformFind)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
}
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
EntityListIterator listIt = (EntityListIterator) resultPerformFind.get("listIt");
try {
if (UtilValidate.isNotEmpty(listIt)) {
list = listIt.getCompleteList();
listIt.close();
} else {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
}
} catch (GenericEntityException e) {
e.printStackTrace();
}
resultToBirt = ServiceUtil.returnSuccess();
resultToBirt.put("records", list);
return resultToBirt;
}
/**
* Analyse given master and create report design from its data
* Two cases are implemented :
* <ul>
* <li>Entity : data retieval is based on a simple view/entity</li>
* <li>Service : data retrieval is based on service</li>
* </ul>
*/
public static Map<String, Object> createFlexibleReportFromMaster(DispatchContext dctx, Map<String, Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
String reportName = (String) context.get("reportName");
String masterContentId = (String) context.get("contentId");
String description = (String) context.get("description");
String writeFilters = (String) context.get("writeFilters");
GenericValue userLogin = (GenericValue) context.get("userLogin");
GenericValue masterContentAttribute = null;
try {
EntityCondition entityCondition = EntityCondition.makeCondition("contentId", masterContentId);
masterContentAttribute = EntityQuery.use(delegator).from("ContentAttribute").where(entityCondition).queryFirst();
} catch (GenericEntityException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
if (masterContentAttribute == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoAttributeFound", locale));
}
String attrName = masterContentAttribute.getString("attrName");
String reportContentId;
if (attrName.equalsIgnoreCase("Entity")) {
String entityViewName = masterContentAttribute.getString("attrValue");
ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
if (modelEntity == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotExist", locale) + " " + entityViewName);
}
try {
Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterEntityWorkflow", UtilMisc.toMap("entityViewName", entityViewName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
if(ServiceUtil.isError(resultContent)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
}
reportContentId = (String) resultContent.get("contentId");
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
} else if (attrName.equalsIgnoreCase("Service")) {
String serviceName = masterContentAttribute.getString("attrValue");
try {
Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterServiceWorkflow", UtilMisc.toMap("serviceName", serviceName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
if (ServiceUtil.isError(resultContent)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
}
reportContentId = (String) resultContent.get("contentId");
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
} else {
// could create other workflows. WebService? Does it need to be independent from Service workflow?
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotDetermineDataSource", locale));
}
// prepare report form to display to allow override
String textForm;
Map<String, Object> resultFormDisplay;
try {
resultFormDisplay = dispatcher.runSync("prepareFlexibleReportSearchFormToEdit", UtilMisc.toMap("reportContentId", reportContentId, "userLogin", userLogin, "locale", locale));
textForm = (String) resultFormDisplay.get("textForm");
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingDefaultSearchForm", locale).concat(": ").concat(e.getMessage()));
}
Map<String, Object> result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyGenerated", locale).concat(" ").concat(reportName));
result.put("textForm", textForm);
result.put("reportContentId", reportContentId);
return result;
}
// I'm not a big fan of how I did the createFormForDisplay / overrideReportForm. Could probably be improved using a proper formForReport object or something similar.
/**
* Update search form of a report design
*/
public static Map<String, Object> overrideReportForm(DispatchContext dctx, Map<String, Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
String reportContentId = (String) context.get("reportContentId");
String overrideFilters = (String) context.get("overrideFilters");
GenericValue userLogin = (GenericValue) context.get("userLogin");
// safety check : do not accept "${groovy", "${bsh" and "javascript"
String overideFiltersNoWhiteSpace = overrideFilters.replaceAll("\\s", "");
if (overideFiltersNoWhiteSpace.contains("${groovy:") || overideFiltersNoWhiteSpace.contains("${bsh:") || overideFiltersNoWhiteSpace.contains("javascript:")) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnauthorisedCharacter", locale));
}
try {
GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).queryOne();
String dataResourceId = content.getString("dataResourceId");
StringBuffer newForm = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <forms xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://ofbiz.apache.org/dtds/widget-form.xsd\">");
newForm.append(overrideFilters);
newForm.append("</forms>");
Document xmlForm = UtilXml.readXmlDocument(newForm.toString());
dispatcher.runSync("updateElectronicTextForm", UtilMisc.toMap("dataResourceId", dataResourceId, "textData", UtilXml.writeXmlDocument(xmlForm), "userLogin", userLogin, "locale", locale));
} catch (GeneralException | SAXException | ParserConfigurationException | IOException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtSearchFormSuccessfullyOverridde", locale));
}
/**
* Create report design from View/Entity master report
*/
public static Map<String, Object> createFlexibleReportFromMasterEntityWorkflow(DispatchContext dctx, Map<String, Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
String writeFilters = (String) context.get("writeFilters");
GenericValue userLogin = (GenericValue) context.get("userLogin");
String entityViewName = (String) context.get("entityViewName");
ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
String contentId = null;
Map<String, Object> result = ServiceUtil.returnSuccess();
try {
Map<String, Object> resultMapsForGeneration = dispatcher.runSync("prepareFlexibleReportFieldsFromEntity", UtilMisc.toMap("modelEntity", modelEntity, "userLogin", userLogin, "locale", locale));
if (ServiceUtil.isError(resultMapsForGeneration)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultMapsForGeneration));
}
Map<String, String> dataMap = (Map<String, String>) resultMapsForGeneration.get("dataMap");
Map<String, String> fieldDisplayLabels = null;
if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("fieldDisplayLabels"))) {
fieldDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("fieldDisplayLabels");
}
Map<String, String> filterMap = null;
if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterMap"))) {
filterMap = (Map<String, String>) resultMapsForGeneration.get("filterMap");
}
Map<String, String> filterDisplayLabels = null;
if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterDisplayLabels"))) {
filterDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("filterDisplayLabels");
}
contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
// callPerformFindFromBirt is the customMethod for Entity workflow
String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryOne();
String customMethodId = content.getString("customMethodId");
if (UtilValidate.isEmpty(customMethodId)) customMethodId = "CM_FB_PERFORM_FIND";
GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
if (customMethod == null) {
return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
}
result = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
"locale", locale,
"dataMap", dataMap,
"userLogin", userLogin,
"filterMap", filterMap,
"serviceName", customMethod.get("customMethodName"),
"writeFilters", writeFilters,
"rptDesignName", rptDesignFileName,
"fieldDisplayLabels", fieldDisplayLabels,
"filterDisplayLabels", filterDisplayLabels));
if (ServiceUtil.isError(result)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
}
} catch (GeneralException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
result.put("contentId", contentId);
return result;
}
/**
* Create report design from service master report
*/
public static Map<String, Object> createFlexibleReportFromMasterServiceWorkflow(DispatchContext dctx, Map<String, Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
String writeFilters = (String) context.get("writeFilters");
String serviceName = (String) context.get("serviceName");
GenericValue userLogin = (GenericValue) context.get("userLogin");
String masterContentId = (String) context.get("masterContentId");
String contentId = null;
Map<String, Object> result = ServiceUtil.returnSuccess();
try {
GenericValue masterContent = EntityQuery.use(delegator).from("Content").where("contentId", masterContentId).cache().queryOne();
String customMethodId = masterContent.getString("customMethodId");
if (UtilValidate.isEmpty(customMethodId)) {
throw new GeneralException("The master content " + masterContentId + " haven't a customMethod");
}
GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
if (customMethod == null) {
return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
}
String customMethodName = (String) customMethod.getString("customMethodName");
if ("default".equalsIgnoreCase(serviceName)) {
serviceName = customMethodName + "PrepareFields";
}
try {
ModelService modelService = dctx.getModelService(serviceName);
} catch (GenericServiceException e) {
return ServiceUtil.returnError("No service define with name " + serviceName); //TODO labelise
}
contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
Map<String, Object> resultService = dispatcher.runSync(serviceName, UtilMisc.toMap("locale", locale, "userLogin", userLogin));
Map<String, String> dataMap = (Map<String, String>) resultService.get("dataMap");
Map<String, String> filterMap = (Map<String, String>) resultService.get("filterMap");
Map<String, String> fieldDisplayLabels = (Map<String, String>) resultService.get("fieldDisplayLabels");
Map<String, String> filterDisplayLabels = (Map<String, String>) resultService.get("filterDisplayLabels");
Map<String, Object> resultGeneration = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
"locale", locale,
"dataMap", dataMap,
"userLogin", userLogin,
"filterMap", filterMap,
"serviceName", customMethodName,
"writeFilters", writeFilters,
"rptDesignName", rptDesignFileName,
"fieldDisplayLabels", fieldDisplayLabels,
"filterDisplayLabels", filterDisplayLabels));
if (ServiceUtil.isError(resultGeneration)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingFlexibleReport", locale));
}
} catch (GeneralException e) {
return ServiceUtil.returnError(e.getMessage());
}
result.put("contentId", contentId);
return result;
}
/**
* Define which data fields and its label, filter fields and label that will be supported by the View/Entity report design
*/
public static Map<String, Object> prepareFlexibleReportFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
Locale locale = (Locale) context.get("locale");
ModelEntity modelEntity = (ModelEntity) context.get("modelEntity");
Map<String, String> dataMap = new HashMap<String, String>();
Map<String, String> fieldDisplayLabels = new HashMap<String, String>();
LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, String>();
LinkedHashMap<String, String> filterDisplayLabels = new LinkedHashMap<String, String>();
List<String> listEntityFields = modelEntity.getAllFieldNames();
Map<Object, Object> uiLabelMap = new HashMap<Object, Object>();
final String[] resourceGlob = {"OrderUiLabels", "ProductUiLabels", "PartyUiLabels", "ContentUiLabels", "AccountingUiLabels", "CommonUiLabels", "BirtUiLabels"};
for (String res : resourceGlob) {
uiLabelMap.putAll(UtilProperties.getProperties(res, locale));
}
List<String> excludeFields = modelEntity.getAutomaticFieldNames();
for (String field : listEntityFields) {
ModelField mField = modelEntity.getField(field);
//ignore stamps fields
if (excludeFields.contains(mField.getName())) continue;
dataMap.put(field, mField.getType());
String localizedName = null;
String interpretedFieldName = null;
FlexibleStringExpander.getInstance(mField.getDescription()).expandString(context);
String titleFieldName = "FormFieldTitle_".concat(field);
localizedName = (String) uiLabelMap.get(titleFieldName);
if (UtilValidate.isEmpty(localizedName) || localizedName.equals(titleFieldName)) {
interpretedFieldName = FlexibleStringExpander.getInstance(field).expandString(context);
fieldDisplayLabels.put(field, interpretedFieldName);
} else {
fieldDisplayLabels.put(field, localizedName);
}
List<String> fieldTypeWithRangeList = UtilMisc.toList("date", "date-time", "time", "floating-point", "currency-amount", "numeric");
if (fieldTypeWithRangeList.contains(mField.getType())) {
filterMap.put(field.concat("_fld0_value"), mField.getType());
filterMap.put(field.concat("_fld0_op"), "short-varchar");
filterMap.put(field.concat("_fld1_value"), mField.getType());
filterMap.put(field.concat("_fld1_op"), "short-varchar");
filterDisplayLabels.put(field.concat("_fld0_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale)));
filterDisplayLabels.put(field.concat("_fld0_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
filterDisplayLabels.put(field.concat("_fld1_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale)));
filterDisplayLabels.put(field.concat("_fld1_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
} else { // remaining types need 4 fields (fld0-1_op-value)
filterMap.put(field, mField.getType());
filterMap.put(field.concat("_op"), "short-varchar");
filterDisplayLabels.put(field, fieldDisplayLabels.get(field));
filterDisplayLabels.put(field.concat("_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale)));
}
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("dataMap", dataMap);
if (UtilValidate.isNotEmpty(fieldDisplayLabels)) {
result.put("fieldDisplayLabels", fieldDisplayLabels);
}
if (UtilValidate.isNotEmpty(filterMap)) {
result.put("filterMap", filterMap);
}
if (UtilValidate.isNotEmpty(filterDisplayLabels)) {
result.put("filterDisplayLabels", filterDisplayLabels);
}
return result;
}
/**
* Prepare and return search form of a report design
*/
public static Map<String, Object> createFormForDisplay(DispatchContext dctx, Map<String, Object> context) {
String reportContentId = (String) context.get("reportContentId");
Delegator delegator = dctx.getDelegator();
Map<String, Object> result = ServiceUtil.returnSuccess();
String textData = null;
try {
GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).cache().queryOne();
String dataResourceId = content.getString("dataResourceId");
GenericValue electronicText = EntityQuery.use(delegator).from("ElectronicText").where("dataResourceId", dataResourceId).cache().queryOne();
textData = electronicText.getString("textData");
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (Debug.infoOn()) Debug.logInfo(textData, module);
textData = textData.substring(textData.indexOf("<form "), textData.length());
if (textData.contains("</form>")) {
textData = textData.substring(0, textData.indexOf("</form>") + 7);
} else {
textData = textData.substring(0, textData.indexOf("/>") + 2);
}
textData = StringUtil.replaceString(textData, "$", "&#36;");
result.put("textForm", textData);
return result;
}
/**
* delete all non-master report design
*/
public static Map<String, Object> deleteAllReports(DispatchContext dctx, Map<String, Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
List<String> listContentId = null;
List<GenericValue> listContent = null;
EntityCondition entityConditionContent = EntityCondition.makeCondition("contentTypeId", "FLEXIBLE_REPORT");
try {
listContent = EntityQuery.use(delegator).from("Content").where(entityConditionContent).select("contentId").queryList();
} catch (GenericEntityException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
if (UtilValidate.isEmpty(listContent)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoFlexibleReportToDelete", locale));
}
listContentId = EntityUtil.getFieldListFromEntityList(listContent, "contentId", true);
try {
for (String contentId : listContentId) {
Map<String, Object> returnMap = dispatcher.runSync("deleteFlexibleReport", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
ServiceUtil.isError(returnMap);
}
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportsSuccessfullyDeleted", locale));
}
/**
* Delete a flexible report design
*/
public static Map<String, Object> deleteFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
String contentId = (String) context.get("contentId");
List<GenericValue> listContentRpt = null;
List<GenericValue> listRptDesignFileGV = null;
String contentIdRpt;
try {
listContentRpt = EntityQuery.use(delegator).from("ContentAssoc").where("contentId", contentId).select("contentIdTo").queryList();
contentIdRpt = listContentRpt.get(0).getString("contentIdTo");
List<EntityExpr> listConditions = UtilMisc.toList(EntityCondition.makeCondition("contentTypeId", EntityOperator.EQUALS, "RPTDESIGN"), EntityCondition.makeCondition("contentId", EntityOperator.EQUALS, contentIdRpt));
EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(listConditions, EntityOperator.AND);
listRptDesignFileGV = EntityQuery.use(delegator).from("ContentDataResourceView").where(ecl).select("drObjectInfo").queryList();
} catch (GenericEntityException e1) {
e1.printStackTrace();
return ServiceUtil.returnError(e1.getMessage());
}
if (listRptDesignFileGV.size() > 1) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnexpectedNumberReportToDelete", locale));
}
List<String> listRptDesignFile = EntityUtil.getFieldListFromEntityList(listRptDesignFileGV, "drObjectInfo", false);
String rptfileName = listRptDesignFile.get(0);
Path path = Paths.get(rptfileName);
try {
if (! Files.deleteIfExists(path)) {
ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotLocateReportFile", locale));
}
} catch (IOException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
try {
delegator.removeByAnd("ContentAttribute", UtilMisc.toMap("contentId", contentId));
dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentIdRpt, "userLogin", userLogin, "locale", locale));
} catch (GenericServiceException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
} catch (GenericEntityException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyDeleted", locale));
}
/**
* Update birt rptdesign file from uploaded one.
* <p>This will update only STYLES, BODY, MASTERPAGE AND CUBES from existing rptdesign with uploaded ones.</p>
*
*/
public static Map<String, Object> uploadRptDesign(DispatchContext dctx, Map<String, Object> context) {
String dataResourceId = (String) context.get("dataResourceIdRpt");
Locale locale = (Locale) context.get("locale");
Delegator delegator = dctx.getDelegator();
Map<String, Object> result = null;
List<String> listSuccessMessage = new ArrayList<String>();
// the idea is to allow only design to be uploaded. We use the stored file and add the new design from the uploaded file within.
DesignConfig config = new DesignConfig();
IDesignEngine engine = null;
try {
Platform.startup();
IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY);
engine = factory.createDesignEngine(config);
} catch (Exception e) {
e.printStackTrace();
}
SessionHandle session = engine.newSessionHandle(ULocale.forLocale(locale));
// get old file to restore dataset and datasource
ByteBuffer newRptDesignBytes = (ByteBuffer) context.get("uploadRptDesign");
if (newRptDesignBytes == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotFindUploadedFile", locale));
}
GenericValue dataResource = null;
try {
dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", dataResourceId).queryOne();
} catch (GenericEntityException e1) {
e1.printStackTrace();
return ServiceUtil.returnError(e1.getMessage());
}
String rptDesignName = dataResource.getString("objectInfo");
// start Birt API platfrom
try {
Platform.startup();
} catch (BirtException e) {
e.printStackTrace();
return ServiceUtil.returnError("Cannot start Birt platform");
}
// get database design
ReportDesignHandle designStored;
try {
designStored = session.openDesign(rptDesignName);
} catch (DesignFileException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
// check if design stored already has a body and delete it to avoid conflicts (taking into account only newly designed body)
if (UtilValidate.isNotEmpty(designStored.getBody())) {
SlotHandle bodyStored = designStored.getBody();
Iterator<DesignElementHandle> iter = bodyStored.iterator();
while (iter.hasNext()) {
try {
iter.remove();
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
}
}
// NEED TO COPY STYLES, BODY, MASTERPAGE AND CUBES; existing elements (in case I missed one):
//[styles, parameters, dataSources, dataSets, pageSetup, components, body, scratchPad, templateParameterDefinitions, cubes, themes]
// get user design
String nameTempRpt = rptDesignName.substring(0, rptDesignName.lastIndexOf('.')).concat("_TEMP_.rptdesign");
File file = new File(nameTempRpt);
RandomAccessFile out;
ReportDesignHandle designFromUser;
try {
out = new RandomAccessFile(file, "rw");
out.write(newRptDesignBytes.array());
out.close();
designFromUser = session.openDesign(nameTempRpt);
// user file is deleted straight away to prevent the use of the report as script entry (security)
Path path = Paths.get(nameTempRpt);
Files.deleteIfExists(path);
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
//copy cube
SlotHandle cubesFromUser = designFromUser.getCubes();
Iterator<DesignElementHandle> iterCube = cubesFromUser.iterator();
while (iterCube.hasNext()) {
DesignElementHandle item = (DesignElementHandle) iterCube.next();
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getCubes().add(copy);
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
}
// copy body
SlotHandle bodyFromUser = designFromUser.getBody();
Iterator<DesignElementHandle> iter = bodyFromUser.iterator();
while (iter.hasNext()) {
DesignElementHandle item = (DesignElementHandle) iter.next();
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getBody().add(copy);
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
}
// deleting simple master page from design stored
try {
List<DesignElementHandle> listMasterPagesStored = designStored.getMasterPages().getContents();
for (Object masterPage : listMasterPagesStored) {
if (masterPage instanceof SimpleMasterPageHandle) {
designStored.getMasterPages().drop((DesignElementHandle) masterPage);
}
}
// adding simple master page => tous ces casts et autres instanceof... c'est laid, mais c'est tellement galère que quand je trouve une solution qui marche... :s
List<DesignElementHandle> listMasterPages = designFromUser.getMasterPages().getContents();
for (DesignElementHandle masterPage : listMasterPages) {
if (masterPage instanceof SimpleMasterPageHandle) {
designStored.getMasterPages().add((SimpleMasterPage) ((SimpleMasterPageHandle) masterPage).copy());
}
}
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
// page variables
List<VariableElementHandle> pageVariablesUser = designFromUser.getPageVariables();
for (VariableElementHandle pageVariable : pageVariablesUser) {
try {
designStored.setPageVariable(pageVariable.getName(), pageVariable.getPropertyBindingExpression(pageVariable.getName()));
} catch (SemanticException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
}
// copy styles
SlotHandle stylesFromUser = designFromUser.getStyles();
SlotHandle stylesStored = designStored.getStyles();
// getting style names from stored report
List<String> listStyleNames = new ArrayList<String>();
Iterator<DesignElementHandle> iterStored = stylesStored.iterator();
while (iterStored.hasNext()) {
DesignElementHandle item = (DesignElementHandle) iterStored.next();
listStyleNames.add(item.getName());
}
Iterator<DesignElementHandle> iterUser = stylesFromUser.iterator();
// adding to styles those which are not already present
while (iterUser.hasNext()) {
DesignElementHandle item = (DesignElementHandle) iterUser.next();
if (! listStyleNames.contains(item.getName())) {
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getStyles().add(copy);
} catch (Exception e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
}
}
try {
designStored.saveAs(rptDesignName);
} catch (IOException e) {
e.printStackTrace();
return ServiceUtil.returnError(e.getMessage());
}
designFromUser.close();
designStored.close();
if (Debug.infoOn()) Debug.logInfo("####### Design uploaded: ".concat(rptDesignName), module);
// should we as a secondary safety precaution delete any file finishing with _TEMP_.rptdesign?
listSuccessMessage.add(UtilProperties.getMessage(resource, "BirtFlexibleRptDesignSuccessfullyUploaded", locale));
result = ServiceUtil.returnSuccess(listSuccessMessage);
return result;
}
}