in birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java [694:895]
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<>();
// 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) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
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(RES_ERROR, "BirtErrorCannotFindUploadedFile", locale));
}
GenericValue dataResource = null;
try {
dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", dataResourceId).queryOne();
} catch (GenericEntityException e1) {
Debug.logError(e1, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
String rptDesignName = dataResource.getString("objectInfo");
// start Birt API platfrom
try {
Platform.startup();
} catch (BirtException e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Cannot start Birt platform");
}
// get database design
ReportDesignHandle designStored;
try {
designStored = session.openDesign(rptDesignName);
} catch (DesignFileException e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
// 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();
@SuppressWarnings("unchecked")
Iterator<DesignElementHandle> iter = bodyStored.iterator();
while (iter.hasNext()) {
try {
iter.remove();
} catch (Exception e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
}
}
// 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 (DesignFileException | IOException e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError(UtilProperties.getMessage(RES_ERROR, "BirtErrorInuploadRptDesignNoFile", locale));
}
//copy cube
SlotHandle cubesFromUser = designFromUser.getCubes();
@SuppressWarnings("unchecked")
Iterator<DesignElementHandle> iterCube = cubesFromUser.iterator();
while (iterCube.hasNext()) {
DesignElementHandle item = iterCube.next();
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getCubes().add(copy);
} catch (Exception e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
}
// copy body
SlotHandle bodyFromUser = designFromUser.getBody();
@SuppressWarnings("unchecked")
Iterator<DesignElementHandle> iter = bodyFromUser.iterator();
while (iter.hasNext()) {
DesignElementHandle item = iter.next();
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getBody().add(copy);
} catch (Exception e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
}
// deleting simple master page from design stored
try {
@SuppressWarnings("unchecked")
List<DesignElementHandle> listMasterPagesStored = designStored.getMasterPages().getContents();
for (Object masterPage : listMasterPagesStored) {
if (masterPage instanceof SimpleMasterPageHandle) {
designStored.getMasterPages().drop((DesignElementHandle) masterPage);
}
}
// FXIME ? adding simple master page => All these casts and other occurrences ... It's ugly, but it's so hard that when I find a
// solution that works ...
@SuppressWarnings("unchecked")
List<DesignElementHandle> listMasterPages = designFromUser.getMasterPages().getContents();
for (DesignElementHandle masterPage : listMasterPages) {
if (masterPage instanceof SimpleMasterPageHandle) {
SimpleMasterPageHandle masterPageHandle = (SimpleMasterPageHandle) masterPage;
designStored.getMasterPages().add(masterPageHandle.copy().getHandle(masterPage.getModule()));
}
}
} catch (Exception e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
// page variables
List<VariableElementHandle> pageVariablesUser = designFromUser.getPageVariables();
for (VariableElementHandle pageVariable : pageVariablesUser) {
try {
designStored.setPageVariable(pageVariable.getName(), pageVariable.getPropertyBindingExpression(pageVariable.getName()));
} catch (SemanticException e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
}
// copy styles
SlotHandle stylesFromUser = designFromUser.getStyles();
SlotHandle stylesStored = designStored.getStyles();
// getting style names from stored report
List<String> listStyleNames = new ArrayList<>();
@SuppressWarnings("unchecked")
Iterator<DesignElementHandle> iterStored = stylesStored.iterator();
while (iterStored.hasNext()) {
DesignElementHandle item = iterStored.next();
listStyleNames.add(item.getName());
}
@SuppressWarnings("unchecked")
Iterator<DesignElementHandle> iterUser = stylesFromUser.iterator();
// adding to styles those which are not already present
while (iterUser.hasNext()) {
DesignElementHandle item = iterUser.next();
if (!listStyleNames.contains(item.getName())) {
DesignElementHandle copy = item.copy().getHandle(item.getModule());
try {
designStored.getStyles().add(copy);
} catch (Exception e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
}
}
try {
designStored.saveAs(rptDesignName);
} catch (IOException e) {
Debug.logError(e, MODULE);
return ServiceUtil.returnError("Error in uploadRptDesign service."); //TODO labelise
}
designFromUser.close();
designStored.close();
if (Debug.infoOn()) {
Debug.logInfo("####### Design uploaded: ".concat(rptDesignName), MODULE);
}
// TODO check: 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;
}