Added: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java?rev=1780683&view=auto ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java (added) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java Sat Jan 28 13:22:55 2017 @@ -0,0 +1,823 @@ +/******************************************************************************* + * 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; + } + +} \ No newline at end of file Added: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtUtil.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtUtil.java?rev=1780683&view=auto ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtUtil.java (added) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtUtil.java Sat Jan 28 13:22:55 2017 @@ -0,0 +1,261 @@ +/******************************************************************************* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.OutputStream; +import java.io.StringWriter; +import java.sql.SQLException; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.apache.commons.collections4.MapUtils; +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.UtilGenerics; +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.template.FreeMarkerWorker; +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.util.EntityUtil; +import org.apache.ofbiz.security.Security; +import org.apache.ofbiz.service.GenericServiceException; +import org.apache.ofbiz.service.LocalDispatcher; +import org.eclipse.birt.report.engine.api.EXCELRenderOption; +import org.eclipse.birt.report.engine.api.EngineException; +import org.eclipse.birt.report.engine.api.HTMLRenderOption; +import org.eclipse.birt.report.engine.api.HTMLServerImageHandler; +import org.eclipse.birt.report.engine.api.IPDFRenderOption; +import org.eclipse.birt.report.engine.api.IReportEngine; +import org.eclipse.birt.report.engine.api.IReportRunnable; +import org.eclipse.birt.report.engine.api.IRunAndRenderTask; +import org.eclipse.birt.report.engine.api.PDFRenderOption; +import org.eclipse.birt.report.engine.api.RenderOption; +import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants; + +public final class BirtUtil { + + public final static String module = BirtUtil.class.getName(); + + private final static HTMLServerImageHandler imageHandler = new HTMLServerImageHandler(); + private final static Map<String, String> entityFieldTypeBirtTypeMap = MapUtils.unmodifiableMap(UtilMisc.toMap( + "id", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "url", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "name", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "id-ne", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "value", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "email", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "comment", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "id-long",DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "id-vlong", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "very-long", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "indicator", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "very-short", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "tel-number", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "id-long-ne", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "id-vlong-ne", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "description", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "long-varchar", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "short-varchar", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "credit-card-date", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "credit-card-number", DesignChoiceConstants.COLUMN_DATA_TYPE_STRING, + "date-time", DesignChoiceConstants.COLUMN_DATA_TYPE_DATETIME, + "date", DesignChoiceConstants.COLUMN_DATA_TYPE_DATE, + "time", DesignChoiceConstants.COLUMN_DATA_TYPE_TIME, + "currency-amount", DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, + "currency-precise", DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, + "fixed-point", DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, + "floating-point", DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL, + "numeric", DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER, + "object", DesignChoiceConstants.COLUMN_DATA_TYPE_JAVA_OBJECT, + "blob", DesignChoiceConstants.COLUMN_DATA_TYPE_BLOB)); + + private final static Map<String, String> entityFieldTypeBirtParameterTypeMap = MapUtils.unmodifiableMap(UtilMisc.toMap( + "id", DesignChoiceConstants.PARAM_TYPE_STRING, + "url", DesignChoiceConstants.PARAM_TYPE_STRING, + "name", DesignChoiceConstants.PARAM_TYPE_STRING, + "id-ne", DesignChoiceConstants.PARAM_TYPE_STRING, + "value", DesignChoiceConstants.PARAM_TYPE_STRING, + "email", DesignChoiceConstants.PARAM_TYPE_STRING, + "comment", DesignChoiceConstants.PARAM_TYPE_STRING, + "id-long",DesignChoiceConstants.PARAM_TYPE_STRING, + "id-vlong", DesignChoiceConstants.PARAM_TYPE_STRING, + "very-long", DesignChoiceConstants.PARAM_TYPE_STRING, + "indicator", DesignChoiceConstants.PARAM_TYPE_STRING, + "very-short", DesignChoiceConstants.PARAM_TYPE_STRING, + "tel-number", DesignChoiceConstants.PARAM_TYPE_STRING, + "id-long-ne", DesignChoiceConstants.PARAM_TYPE_STRING, + "id-vlong-ne", DesignChoiceConstants.PARAM_TYPE_STRING, + "description", DesignChoiceConstants.PARAM_TYPE_STRING, + "long-varchar", DesignChoiceConstants.PARAM_TYPE_STRING, + "short-varchar", DesignChoiceConstants.PARAM_TYPE_STRING, + "credit-card-date", DesignChoiceConstants.PARAM_TYPE_STRING, + "credit-card-number", DesignChoiceConstants.PARAM_TYPE_STRING, + "date-time", DesignChoiceConstants.PARAM_TYPE_DATETIME, + "date", DesignChoiceConstants.PARAM_TYPE_DATE, + "time", DesignChoiceConstants.PARAM_TYPE_TIME, + "currency-amount", DesignChoiceConstants.PARAM_TYPE_DECIMAL, + "currency-precise", DesignChoiceConstants.PARAM_TYPE_DECIMAL, + "fixed-point", DesignChoiceConstants.PARAM_TYPE_DECIMAL, + "floating-point", DesignChoiceConstants.PARAM_TYPE_DECIMAL, + "numeric", DesignChoiceConstants.PARAM_TYPE_INTEGER, + "object", DesignChoiceConstants.PARAM_TYPE_JAVA_OBJECT, + "blob", DesignChoiceConstants.PARAM_TYPE_JAVA_OBJECT)); + + private final static Map<String, String> mimeTypeOutputFormatMap = UtilMisc.toMap( + "text/html", RenderOption.OUTPUT_FORMAT_HTML, + "application/pdf", RenderOption.OUTPUT_FORMAT_PDF, + "application/postscript", "postscript", + "application/vnd.ms-word", "doc", + "application/vnd.ms-excel", "xls", + "application/vnd.ms-powerpoint", "ppt", + "application/vnd.oasis.opendocument.text", "odt", + "application/vnd.oasis.opendocument.spreadsheet", "ods", + "application/vnd.oasis.opendocument.presentation", "odp", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"); + + private BirtUtil() {} + + /** + * Return birt field type corresponding to given entity field type + * @param entityFieldType + * @return + * @throws GeneralException + */ + public static String convertFieldTypeToBirtType(String entityFieldType) { + if (UtilValidate.isEmpty(entityFieldType)) { + return null; + } + return entityFieldTypeBirtTypeMap.get(entityFieldType.toLowerCase()); + } + + /** + * Return birt parameter type corresponding to given entity field type + * @param entityFieldType + * @return + * @throws GeneralException + */ + public static String convertFieldTypeToBirtParameterType(String entityFieldType) { + if (UtilValidate.isEmpty(entityFieldType)) { + return null; + } + return entityFieldTypeBirtParameterTypeMap.get(entityFieldType.toLowerCase()); + } + + /** + * Return true if mime type related to a contentType is supported by Birt + * @param contentType + * @return + * @throws GeneralException + */ + public static boolean isSupportedMimeType(String contentType) { + return mimeTypeOutputFormatMap.containsKey(contentType); + } + + /** + * Return mime type related to a contentType supported by Birt + * @param contentType + * @return + * @throws GeneralException + */ + public static String getMimeTypeOutputFormat(String contentType) throws GeneralException { + if (isSupportedMimeType(contentType)) { + return mimeTypeOutputFormatMap.get(contentType); + } + throw new GeneralException("Unknown content type : " + contentType); + } + + /** + * return extension file related to a contentType supported by Birt + * @param contentType + * @return + * @throws GeneralException + */ + public static String getMimeTypeFileExtension(String contentType) throws GeneralException { + return ".".concat(getMimeTypeOutputFormat(contentType)); + } + + /** + * Resolve the template path location where rptDesign file are stored, + * first try the resolution from birt.properties with rptDesign.output.path + * second from content.properties content.upload.path.prefix + * and add birtReptDesign directory + * default OFBIZ_HOME/runtime/uploads/birtRptDesign/ + * @return + */ + public static String resolveTemplatePathLocation() { + String templatePathLocation = UtilProperties.getPropertyValue("birt", "rptDesign.output.path"); + if (UtilValidate.isEmpty(templatePathLocation)) { + templatePathLocation = UtilProperties.getPropertyValue("content", "content.upload.path.prefix", "runtime/uploads"); + } + if (! templatePathLocation.endsWith("/")) { + templatePathLocation = templatePathLocation.concat("/"); + } + if (! templatePathLocation.endsWith("/birtRptDesign/")) { + templatePathLocation = templatePathLocation.concat("birtRptDesign/"); + } + if (! templatePathLocation.startsWith("/")) templatePathLocation = System.getProperty("ofbiz.home").concat("/").concat(templatePathLocation); + return templatePathLocation; + } + + /** + * With the reporting contentId element resolve the path to rptDesign linked + * @param delegator + * @param contentId + * @return + * @throws GenericEntityException + */ + public static String resolveRptDesignFilePathFromContent(Delegator delegator, String contentId) throws GenericEntityException { + List<GenericValue> listContentRpt = delegator.findList("ContentAssoc", EntityCondition.makeCondition("contentId", contentId), UtilMisc.toSet("contentIdTo"), null, null, true); + if (UtilValidate.isNotEmpty(listContentRpt)) { + String contentIdRpt = EntityUtil.getFirst(listContentRpt).getString("contentIdTo"); + List<EntityExpr> listConditions = UtilMisc.toList( + EntityCondition.makeCondition("contentTypeId", "RPTDESIGN"), + EntityCondition.makeCondition("contentId", contentIdRpt)); + EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(listConditions); + List<GenericValue> listDataRessouceRptDesignFile = delegator.findList("ContentDataResourceView", ecl, UtilMisc.toSet("drObjectInfo"), null, null, true); + if (UtilValidate.isNotEmpty(listDataRessouceRptDesignFile)) { + return EntityUtil.getFirst(listDataRessouceRptDesignFile).getString("drObjectInfo"); + } + } + return ""; + } + + /** + * remove all non unicode alphanumeric and replace space by _ + * @param reportName + * @return + */ + public static String encodeReportName(String reportName) { + if (UtilValidate.isEmpty(reportName)) return ""; + return StringUtil.replaceString(StringUtil.removeRegex(reportName.trim(), "[^\\p{L}\\s]"), " ", "_"); + } +} \ No newline at end of file Added: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/ReportDesignGenerator.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/ReportDesignGenerator.java?rev=1780683&view=auto ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/ReportDesignGenerator.java (added) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/ReportDesignGenerator.java Sat Jan 28 13:22:55 2017 @@ -0,0 +1,344 @@ +package org.apache.ofbiz.birt.flexible; + +import com.ibm.icu.util.ULocale; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.GeneralException; +import org.apache.ofbiz.base.util.UtilProperties; +import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.entity.GenericValue; +import org.apache.ofbiz.service.DispatchContext; +import org.apache.ofbiz.service.GenericServiceException; +import org.eclipse.birt.core.framework.Platform; +import org.eclipse.birt.report.model.api.CachedMetaDataHandle; +import org.eclipse.birt.report.model.api.CellHandle; +import org.eclipse.birt.report.model.api.DataItemHandle; +import org.eclipse.birt.report.model.api.DesignConfig; +import org.eclipse.birt.report.model.api.DesignElementHandle; +import org.eclipse.birt.report.model.api.ElementFactory; +import org.eclipse.birt.report.model.api.GridHandle; +import org.eclipse.birt.report.model.api.IDesignEngine; +import org.eclipse.birt.report.model.api.IDesignEngineFactory; +import org.eclipse.birt.report.model.api.LabelHandle; +import org.eclipse.birt.report.model.api.PropertyHandle; +import org.eclipse.birt.report.model.api.ReportDesignHandle; +import org.eclipse.birt.report.model.api.RowHandle; +import org.eclipse.birt.report.model.api.ScalarParameterHandle; +import org.eclipse.birt.report.model.api.ScriptDataSetHandle; +import org.eclipse.birt.report.model.api.ScriptDataSourceHandle; +import org.eclipse.birt.report.model.api.SessionHandle; +import org.eclipse.birt.report.model.api.StructureFactory; +import org.eclipse.birt.report.model.api.activity.SemanticException; +import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants; +import org.eclipse.birt.report.model.api.elements.structures.CachedMetaData; +import org.eclipse.birt.report.model.api.elements.structures.ColumnHint; +import org.eclipse.birt.report.model.api.elements.structures.ComputedColumn; +import org.eclipse.birt.report.model.api.elements.structures.HideRule; +import org.eclipse.birt.report.model.api.elements.structures.ResultSetColumn; +import org.eclipse.birt.report.model.elements.ReportItem; + +/** + * Report Design Generator Object - Handles flexible report design Generation from Master. + */ + +public class ReportDesignGenerator { + + private static final String module = ReportDesignGenerator.class.getName(); + private Locale locale; + private ElementFactory factory; + /** The generated design */ + private ReportDesignHandle design; + private Map<String, String> dataMap; + /** Map of all filter supported by the report design */ + private Map<String, String> filterMap; + /** Service name to populate dataset of the report design*/ + private String serviceName; + private Map<String, String> fieldDisplayLabels; + private Map<String, String> filterDisplayLabels; + private String rptDesignName; + private boolean generateFilters = false; + private GenericValue userLogin; + + public static final String resource_error = "BirtErrorUiLabels"; + + public ReportDesignGenerator(Map<String, Object> context, DispatchContext dctx) throws GeneralException, SemanticException { + locale = (Locale) context.get("locale"); + dataMap = (Map<String, String>) context.get("dataMap"); + filterMap = (LinkedHashMap<String, String>) context.get("filterMap"); + serviceName = (String) context.get("serviceName"); + fieldDisplayLabels = (Map<String, String>) context.get("fieldDisplayLabels"); + filterDisplayLabels = (LinkedHashMap<String, String>) context.get("filterDisplayLabels"); + rptDesignName = (String) context.get("rptDesignName"); + String writeFilters = (String) context.get("writeFilters"); + userLogin = (GenericValue) context.get("userLogin"); + if (UtilValidate.isEmpty(dataMap)) { + throw new GeneralException("Report design generator failed. Entry data map not found."); + } + if ("Y".equals(writeFilters)) { + generateFilters = true; + } + } + + /** + * Generate report design (rtdesign file). + * @throws IOException + * @throws SemanticException + * @throws GeneralException + */ + public void buildReport() throws IOException, SemanticException, GeneralException { + 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) { + throw new GeneralException(e.getMessage()); + } + + // creating main design elements + SessionHandle session = engine.newSessionHandle(ULocale.forLocale(locale)); + design = session.createDesign(); + + factory = design.getElementFactory(); + + DesignElementHandle element = factory.newSimpleMasterPage("Page Master"); + design.getMasterPages().add(element); + + // create DataSource call + createScriptedDataSource(); + + // create DataSet call + try { + createScriptedDataset(); + } catch (SemanticException se) { + throw se; + } catch (GenericServiceException gse) { + throw gse; + } + + // General design parameters + design.setLayoutPreference(DesignChoiceConstants.REPORT_LAYOUT_PREFERENCE_AUTO_LAYOUT); + design.setBidiOrientation(DesignChoiceConstants.BIDI_DIRECTION_LTR); + design.setDefaultUnits(DesignChoiceConstants.UNITS_IN); + design.setCreatedBy(design.getVersion()); + design.setImageDPI(96); + + // adding filters as parameters to make them available for design + // first adding parameters to the design itself + if (UtilValidate.isNotEmpty(filterMap)) { + // adding filters within reportDesign if generateFilters is set to true + GridHandle grid = null; + int i = 0; + if (generateFilters) { + grid = factory.newGridItem(null, 2, filterMap.size()); + design.getBody().add(grid); + grid.setWidth("100%"); + } + + for (String filter : filterMap.keySet()) { + String birtType = BirtUtil.convertFieldTypeToBirtParameterType(filterMap.get(filter)); + if (birtType == null) { + throw new GeneralException(UtilProperties.getMessage(resource_error, "BirtErrorConversionFieldToBirtFailed", locale)); + } + // get label + String displayFilterName; + if (UtilValidate.isNotEmpty(filterDisplayLabels)) { + displayFilterName = filterDisplayLabels.get(filter); + } else { + displayFilterName = filter; + } + ScalarParameterHandle scalParam = factory.newScalarParameter(filter); +// scalParam.setDisplayName(displayFilterName); // has no incidence at all right now, is only displayed when using birt's report parameter system. Not our case. I leave it here if any idea arise of how to translate these. + scalParam.setPromptText(displayFilterName); + if ("javaObject".equals(birtType)) { //Fields of type='blob' are rejected by Birt: org.eclipse.birt.report.model.api.metadata.PropertyValueException: The choice value "javaObject" is not allowed. + throw new GeneralException("Fields of type='blob' are rejected by Birt. Create a view entity, based on the requested entity, where you exclude the field of type='blob'"); + } else { + scalParam.setDataType(birtType); + } + scalParam.setIsRequired(false); + design.getParameters().add(scalParam); + + if (generateFilters) { + RowHandle row = (RowHandle) grid.getRows().get(i); + CellHandle cellLabel = (CellHandle) row.getCells().get(0); + CellHandle cellFilter = (CellHandle) row.getCells().get(1); + LabelHandle label = factory.newLabel(null); + label.setText(displayFilterName); + cellLabel.getContent().add(label); + + // 1. create computed column and add it to grid column bindings + ComputedColumn computedCol = StructureFactory.createComputedColumn(); + PropertyHandle computedSet = grid.getColumnBindings(); + computedCol.setName(displayFilterName); + StringBuffer expression = new StringBuffer("params[\""); + expression.append(filter); + expression.append("\"]"); + computedCol.setExpression(expression.toString()); + computedSet.addItem(computedCol); + + // 2. create data and add computed column to it + DataItemHandle data = factory.newDataItem(null); + data.setResultSetColumn(computedCol.getName()); + cellFilter.getContent().add(data); + + // add visibility rule on row + HideRule hideRule = StructureFactory.createHideRule(); + StringBuffer expressionHide = new StringBuffer(expression); + expressionHide.append(".value == null || "); + expressionHide.append(expression); + expressionHide.append(".value == \"\""); + hideRule.setExpression(expressionHide.toString()); + PropertyHandle propVisHandle = row.getPropertyHandle(ReportItem.VISIBILITY_PROP); + propVisHandle.addItem(hideRule); + i++; + } + } + // second adding script within beforeFactory filling the parameters with values from inputFields + createScriptedBeforeFactory(); + } + + // ################ CODE HERE IF YOU WANT TO ADD GENERATED DESIGN / MAY BE WORTH USING RPTTEMPLATE AND-OR RPTLIBRARY ################### + + //GridHandle grid = factory.newGridItem(null, 7, 3); +// design.getBody().add(grid); + +// grid.setWidth("100%"); + +// RowHandle row = (RowHandle) grid.getRows().get(0); + +// ImageHandle image = factory.newImage(null); + +// CellHandle cell = (CellHandle) row.getCells().get(0); +// cell.getContent().add(image); +// image.setURL("http://ofbiz.apache.org/images/ofbiz_logo.gif"); + +// LabelHandle label = factory.newLabel(null); +// cell = (CellHandle) row.getCells().get(1); +// cell.getContent().add(label); +// label.setText("Dat is dat test !"); + // ##################### + design.saveAs(rptDesignName); + design.close(); + if (Debug.infoOn())Debug.logInfo("####### Design generated: " + rptDesignName, module); + session.closeAll(false); + Platform.shutdown(); + } + + /** + * Create the script that will be called within "Before Factory" step in Birt Report rendering process. + * <p>This script is used to populate Birt design parameters from input</p> + */ + private void createScriptedBeforeFactory() { + StringBuffer beforeFactoryScript = new StringBuffer("Debug.logInfo(\"###### In beforeFactory\", module);\n"); + beforeFactoryScript.append("var inputFields = reportContext.getParameterValue(\"parameters\");\n"); + beforeFactoryScript.append("//get a list of all report parameters\n"); + beforeFactoryScript.append("var parameters = reportContext.getDesignHandle().getAllParameters();\n"); + beforeFactoryScript.append("for (var i = 0; i < parameters.size(); i++) {\n"); + beforeFactoryScript.append(" var currentParam = parameters.get(i);\n"); + beforeFactoryScript.append(" var parametersName = currentParam.getName();\n"); + beforeFactoryScript.append(" params[parametersName].value = inputFields.get(parametersName);\n"); + beforeFactoryScript.append("}"); + design.setBeforeFactory(beforeFactoryScript.toString()); + } + + /** + * Create the script that will define the OFBiz dataset in Birt Report design. + * <p>This dataset will populate the OFBiz datasource of the design + * with <code>records</code> returned by <code>serviceName</code> service</p> + * @throws SemanticException + * @throws GeneralException + */ + private void createScriptedDataset() throws SemanticException, GeneralException { + ScriptDataSetHandle dataSetHandle = factory.newScriptDataSet("Data Set"); + dataSetHandle.setDataSource("OFBiz"); + + // set Initialize Birt script + StringBuffer dataSetInitializeScript = new StringBuffer(); + dataSetInitializeScript.append("importPackage(Packages.org.eclipse.birt.report.engine.api);\n"); + dataSetInitializeScript.append("importPackage(Packages.org.apache.ofbiz.entity);\n"); + dataSetInitializeScript.append("importPackage(Packages.org.apache.ofbiz.service);\n"); + dataSetInitializeScript.append("importPackage(Packages.org.apache.ofbiz.base.util);\n"); + dataSetInitializeScript.append("importPackage(java.util);\n"); + dataSetInitializeScript.append("module = \"" + rptDesignName + "\";"); + dataSetInitializeScript.append("Debug.logInfo(\"###### In initialize \", module);"); + design.setInitialize(dataSetInitializeScript.toString()); + + // set open Birt script + StringBuffer dataSetOpenScript = new StringBuffer("importPackage(Packages.org.apache.ofbiz.birt);\n"); + dataSetOpenScript.append("Debug.logInfo(\"#### In open\", module)\n"); + dataSetOpenScript.append("try {\n"); + dataSetOpenScript.append(" listRes = dispatcher.runSync(\"" + serviceName + "\", UtilMisc.toMap(\"userLogin\", reportContext.getParameterValue(\"userLogin\"), \"locale\", reportContext.getParameterValue(\"locale\"), \"reportContext\", reportContext));\n"); + dataSetOpenScript.append(" if (ServiceUtil.isError(listRes)) {\n"); + dataSetOpenScript.append(" Debug.logError(ServiceUtil.getErrorMessage(listRes));\n"); + dataSetOpenScript.append(" }\n"); + dataSetOpenScript.append("}\n"); + dataSetOpenScript.append("catch (e) { Debug.logError(e, module); }\n"); + dataSetOpenScript.append("records = listRes.get(\"records\");\n"); + dataSetOpenScript.append("countOfRow = 0;\n"); + dataSetOpenScript.append("totalRow = records.size();\n"); + dataSetHandle.setOpen(dataSetOpenScript.toString()); + + // set fetch Birt script + StringBuffer dataSetFetchScript = new StringBuffer("if (countOfRow == totalRow) return false;\n"); + dataSetFetchScript.append("line = records.get(countOfRow);\n"); + for (String field : dataMap.keySet()) { + dataSetFetchScript.append(field); + dataSetFetchScript.append(" = line.get(\""); + dataSetFetchScript.append(field); + dataSetFetchScript.append("\"); row[\""); + dataSetFetchScript.append(field); + dataSetFetchScript.append("\"] = "); + dataSetFetchScript.append(field); + dataSetFetchScript.append(";\n"); + } + + dataSetFetchScript.append("countOfRow ++;\n"); + dataSetFetchScript.append("return true;"); + dataSetHandle.setFetch(dataSetFetchScript.toString()); + + // #### define dataSet + CachedMetaData cmd = StructureFactory.createCachedMetaData(); + CachedMetaDataHandle cachedMetaDataHandle = dataSetHandle.setCachedMetaData(cmd); + PropertyHandle columnHintsSet = dataSetHandle.getPropertyHandle(ScriptDataSetHandle.COLUMN_HINTS_PROP); + + int i = 1; + for (String field : dataMap.keySet()) { + ResultSetColumn resultSetCol = StructureFactory.createResultSetColumn(); + resultSetCol.setColumnName(field); + String birtType = BirtUtil.convertFieldTypeToBirtType(dataMap.get(field)); + if (birtType == null) { + throw new GeneralException(UtilProperties.getMessage(resource_error, "BirtErrorConversionFieldToBirtFailed", locale)); + } + resultSetCol.setPosition(i); + resultSetCol.setDataType(birtType); + + ColumnHint columnHint = StructureFactory.createColumnHint(); + columnHint.setProperty("columnName", field); + columnHint.setProperty("analysis", "dimension"); + columnHint.setProperty("heading", field); + // get label + String displayName = null; + if (UtilValidate.isNotEmpty(fieldDisplayLabels)) { + displayName = fieldDisplayLabels.get(field); + } else { + displayName = field; + } + columnHint.setProperty("displayName", displayName); + cachedMetaDataHandle.getResultSet().addItem(resultSetCol); + columnHintsSet.addItem(columnHint); + i++; + } + design.getDataSets().add(dataSetHandle); + } + + /** Create new dataSource named OFBiz */ + private void createScriptedDataSource() throws SemanticException { + ScriptDataSourceHandle dataSource = factory.newScriptDataSource("OFBiz"); + design.getDataSources().add(dataSource); + } +} Modified: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtEngineServlet.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtEngineServlet.java?rev=1780683&r1=1780682&r2=1780683&view=diff ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtEngineServlet.java (original) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtEngineServlet.java Sat Jan 28 13:22:55 2017 @@ -23,6 +23,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.ofbiz.base.util.GeneralException; import org.eclipse.birt.core.exception.BirtException; import org.eclipse.birt.report.context.BirtContext; import org.eclipse.birt.report.context.IContext; @@ -39,12 +40,15 @@ public class BirtEngineServlet extends o @Override protected IContext __getContext(HttpServletRequest request, HttpServletResponse response) throws BirtException { - BirtReportServiceFactory.getReportService().setContext(getServletContext( ), null); + BirtReportServiceFactory.getReportService().setContext(getServletContext(), null); // set app context Map<String, Object> appContext = UtilGenerics.cast(ReportEngineService.getInstance().getEngineConfig().getAppContext()); - BirtWorker.setWebContextObjects(appContext, request, response); - + try { + BirtWorker.setWebContextObjects(appContext, request, response); + } catch (GeneralException e) { + throw new BirtException(e.getMessage()); + } return new BirtContext(new ViewerServletRequest(ParameterAccessor.getParameter(request, ParameterAccessor.PARAM_REPORT) , request), response); } Modified: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtViewerServlet.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtViewerServlet.java?rev=1780683&r1=1780682&r2=1780683&view=diff ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtViewerServlet.java (original) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtViewerServlet.java Sat Jan 28 13:22:55 2017 @@ -23,6 +23,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.ofbiz.base.util.GeneralException; import org.eclipse.birt.core.exception.BirtException; import org.eclipse.birt.report.context.BirtContext; import org.eclipse.birt.report.context.IContext; @@ -40,11 +41,15 @@ public class BirtViewerServlet extends V @Override protected IContext __getContext(HttpServletRequest request, HttpServletResponse response) throws BirtException { - BirtReportServiceFactory.getReportService().setContext(getServletContext( ), null); + BirtReportServiceFactory.getReportService().setContext(getServletContext(), null); // set app context Map<String, Object> appContext = UtilGenerics.cast(ReportEngineService.getInstance().getEngineConfig().getAppContext()); - BirtWorker.setWebContextObjects(appContext, request, response); + try { + BirtWorker.setWebContextObjects(appContext, request, response); + } catch (GeneralException e) { + throw new BirtException(e.getMessage()); + } return new BirtContext(new ViewerServletRequest(ParameterAccessor.getParameter(request, ParameterAccessor.PARAM_REPORT) , request), response); Modified: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/webapp/view/BirtViewHandler.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/webapp/view/BirtViewHandler.java?rev=1780683&r1=1780682&r2=1780683&view=diff ============================================================================== --- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/webapp/view/BirtViewHandler.java (original) +++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/webapp/view/BirtViewHandler.java Sat Jan 28 13:22:55 2017 @@ -40,6 +40,7 @@ import org.apache.ofbiz.base.util.UtilHt import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.birt.BirtFactory; import org.apache.ofbiz.birt.BirtWorker; +import org.apache.ofbiz.birt.flexible.BirtUtil; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericEntityException; import org.apache.ofbiz.entity.util.EntityUtilProperties; @@ -75,11 +76,17 @@ public class BirtViewHandler implements IReportEngine engine = org.apache.ofbiz.birt.BirtFactory.getReportEngine(); // open report design IReportRunnable design = null; + + // add dynamic parameter for page + if (UtilValidate.isEmpty(page) || page.equals("ExecuteFlexibleReport")) { + page = (String) request.getParameter("rptDesignFile"); + } + if (page.startsWith("component://")) { InputStream reportInputStream = BirtFactory.getReportInputStreamFromLocation(page); design = engine.openReportDesign(reportInputStream); } else { - design = engine.openReportDesign(servletContext.getRealPath(page)); + design = engine.openReportDesign(page); } Map<String, Object> appContext = UtilGenerics.cast(engine.getConfig().getAppContext()); @@ -99,18 +106,29 @@ public class BirtViewHandler implements locale = UtilHttp.getLocale(request); } - // set output file name - String outputFileName = (String) request.getAttribute(BirtWorker.getBirtOutputFileName()); - if (UtilValidate.isNotEmpty(outputFileName)) { - UtilHttp.setContentDisposition(response, outputFileName); - } - // set override content type - String overrideContentType = (String) request.getAttribute(BirtWorker.getBirtContentType()); + String overrideContentType = (String) request.getParameter(BirtWorker.getBirtContentType()); if (UtilValidate.isNotEmpty(overrideContentType)) { contentType = overrideContentType; } + // set output file name to get also file extension + String outputFileName = (String) request.getParameter(BirtWorker.getBirtOutputFileName()); + if (UtilValidate.isNotEmpty(outputFileName)) { + outputFileName = BirtUtil.encodeReportName(outputFileName); + String format = BirtUtil.getMimeTypeFileExtension(contentType); + if (! outputFileName.endsWith(format)) { + outputFileName = outputFileName.concat(format); + } + outputFileName = UtilHttp.canonicalizeParameter(outputFileName); + response.setHeader("Content-Disposition", "attachment; filename=" + outputFileName); + } + + // checking consistency between Birt content type and response content type + if (! contentType.equals(response.getContentType())) { + response.setContentType(contentType); + } + context.put(BirtWorker.getBirtLocale(), locale); Delegator delegator = (Delegator) request.getAttribute("delegator"); String birtImageDirectory = EntityUtilProperties.getPropertyValue("birt", "birt.html.image.directory", delegator); |
Free forum by Nabble | Edit this page |