| /******************************************************************************* |
| * 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.xml.sax.SAXException; |
| 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.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 com.ibm.icu.util.ULocale; |
| import org.w3c.dom.Document; |
| |
| |
| /** |
| * 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"; |
| |
| /** |
| * Instanciate 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 = EntityUtil.getFirst(delegator.findList("ContentAttribute", entityCondition, null, null, null, false)); |
| } 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 = delegator.findOne("Content", true, UtilMisc.toMap("contentId", reportContentId)); |
| 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 = delegator.findOne("Content", true, "contentId", contentId); |
| String customMethodId = content.getString("customMethodId"); |
| if (UtilValidate.isEmpty(customMethodId)) customMethodId = "CM_FB_PERFORM_FIND"; |
| GenericValue customMethod = delegator.findOne("CustomMethod", true, "customMethodId", customMethodId); |
| 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 = delegator.findOne("Content", true, "contentId", masterContentId); |
| String customMethodId = masterContent.getString("customMethodId"); |
| if (UtilValidate.isEmpty(customMethodId)) { |
| throw new GeneralException("The master content " + masterContentId + " haven't a customMethod"); |
| } |
| GenericValue customMethod = delegator.findOne("CustomMethod", true, "customMethodId", customMethodId); |
| 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 = delegator.findOne("Content", true, "contentId", reportContentId); |
| String dataResourceId = content.getString("dataResourceId"); |
| GenericValue electronicText = delegator.findOne("ElectronicText", true, "dataResourceId", dataResourceId); |
| 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, "$", "$"); |
| 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 = delegator.findList("Content", entityConditionContent, UtilMisc.toSet("contentId"), null, null, false); |
| } 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 = delegator.findList("ContentAssoc", EntityCondition.makeCondition("contentId", EntityOperator.EQUALS, contentId), UtilMisc.toSet("contentIdTo"), null, null, false); |
| 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 = delegator.findList("ContentDataResourceView", ecl, UtilMisc.toSet("drObjectInfo"), null, null, false); |
| } 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 = delegator.findOne("DataResource", false, "dataResourceId", dataResourceId); |
| } 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; |
| } |
| |
| } |