MIFOSX-195: some formatting and clean up whilst testing this issue.

This commit is contained in:
Keith Woodlock
2013-05-07 10:18:54 +01:00
parent d8913ab758
commit e8b8cf4f8a
7 changed files with 434 additions and 562 deletions
@@ -5,8 +5,8 @@
*/ */
package org.mifosplatform.infrastructure.core.service; package org.mifosplatform.infrastructure.core.service;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource; import javax.sql.DataSource;
@@ -28,7 +28,7 @@ import org.springframework.stereotype.Service;
@Service @Service
public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService { public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenantService {
private final Map<Long, DataSource> tenantToDataSourceMap = new ConcurrentHashMap<Long, DataSource>(1); private final Map<Long, DataSource> tenantToDataSourceMap = new HashMap<Long, DataSource>(1);
private final DataSource tenantDataSource; private final DataSource tenantDataSource;
@Autowired @Autowired
@@ -44,9 +44,9 @@ public class TomcatJdbcDataSourcePerTenantService implements DataSourcePerTenant
MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
if (tenant != null) { if (tenant != null) {
synchronized(this.tenantToDataSourceMap) synchronized (this.tenantToDataSourceMap) {
{ // if tenant information available switch to appropriate
// if tenant information available switch to appropriate datasource // datasource
// for that tenant. // for that tenant.
if (this.tenantToDataSourceMap.containsKey(tenant.getId())) { if (this.tenantToDataSourceMap.containsKey(tenant.getId())) {
tenantDataSource = this.tenantToDataSourceMap.get(tenant.getId()); tenantDataSource = this.tenantToDataSourceMap.get(tenant.getId());
@@ -6,7 +6,6 @@
package org.mifosplatform.infrastructure.dataqueries.domain; package org.mifosplatform.infrastructure.dataqueries.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@@ -34,323 +33,222 @@ import com.google.gson.JsonArray;
@Entity @Entity
@Table(name = "stretchy_report", uniqueConstraints = { @UniqueConstraint(columnNames = { "report_name" }, name = "unq_report_name") }) @Table(name = "stretchy_report", uniqueConstraints = { @UniqueConstraint(columnNames = { "report_name" }, name = "unq_report_name") })
public class Report extends AbstractPersistable<Long> { public final class Report extends AbstractPersistable<Long> {
@Column(name = "report_name", nullable = false, unique = true) @Column(name = "report_name", nullable = false, unique = true)
private String reportName; private String reportName;
@Column(name = "report_type", nullable = false) @Column(name = "report_type", nullable = false)
private String reportType; private String reportType;
@Column(name = "report_subtype") @Column(name = "report_subtype")
private String reportSubType; private String reportSubType;
@Column(name = "report_category") @Column(name = "report_category")
private String reportCategory; private String reportCategory;
@Column(name = "description") @Column(name = "description")
private String description; private String description;
@Column(name = "core_report", nullable = false) @Column(name = "core_report", nullable = false)
private boolean coreReport; private boolean coreReport;
// only defines if report should appear in reference app UI List // only defines if report should appear in reference app UI List
@Column(name = "use_report", nullable = false) @Column(name = "use_report", nullable = false)
private boolean useReport; private boolean useReport;
@Column(name = "report_sql") @Column(name = "report_sql")
private String reportSql; private String reportSql;
@LazyCollection(LazyCollectionOption.FALSE) @LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true) @OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true)
private Set<ReportParameterUsage> reportParameterUsages = new HashSet<ReportParameterUsage>(); private final Set<ReportParameterUsage> reportParameterUsages = new HashSet<ReportParameterUsage>();
public static Report fromJson(final JsonCommand command) { public static Report fromJson(final JsonCommand command) {
String reportName = null; String reportName = null;
String reportType = null; String reportType = null;
String reportSubType = null; String reportSubType = null;
String reportCategory = null; String reportCategory = null;
String description = null; String description = null;
boolean useReport = false; boolean useReport = false;
String reportSql = null; String reportSql = null;
if (command.parameterExists("reportName")) if (command.parameterExists("reportName")) reportName = command.stringValueOfParameterNamed("reportName");
reportName = command.stringValueOfParameterNamed("reportName"); if (command.parameterExists("reportType")) reportType = command.stringValueOfParameterNamed("reportType");
if (command.parameterExists("reportType")) if (command.parameterExists("reportSubType")) reportSubType = command.stringValueOfParameterNamed("reportSubType");
reportType = command.stringValueOfParameterNamed("reportType"); if (command.parameterExists("reportCategory")) reportCategory = command.stringValueOfParameterNamed("reportCategory");
if (command.parameterExists("reportSubType")) if (command.parameterExists("description")) description = command.stringValueOfParameterNamed("description");
reportSubType = command if (command.parameterExists("useReport")) useReport = command.booleanPrimitiveValueOfParameterNamed("useReport");
.stringValueOfParameterNamed("reportSubType"); if (command.parameterExists("reportSql")) reportSql = command.stringValueOfParameterNamed("reportSql");
if (command.parameterExists("reportCategory"))
reportCategory = command
.stringValueOfParameterNamed("reportCategory");
if (command.parameterExists("description"))
description = command.stringValueOfParameterNamed("description");
if (command.parameterExists("useReport"))
useReport = command
.booleanPrimitiveValueOfParameterNamed("useReport");
if (command.parameterExists("reportSql"))
reportSql = command.stringValueOfParameterNamed("reportSql");
return new Report(reportName, reportType, reportSubType, return new Report(reportName, reportType, reportSubType, reportCategory, description, useReport, reportSql);
reportCategory, description, useReport, reportSql); }
}
protected Report() { protected Report() {
// //
} }
public Report(final String reportName, final String reportType, public Report(final String reportName, final String reportType, final String reportSubType, final String reportCategory,
final String reportSubType, final String reportCategory, final String description, final boolean useReport, final String reportSql) {
final String description, final boolean useReport, this.reportName = reportName;
final String reportSql) { this.reportType = reportType;
this.reportName = reportName; this.reportSubType = reportSubType;
this.reportType = reportType; this.reportCategory = reportCategory;
this.reportSubType = reportSubType; this.description = description;
this.reportCategory = reportCategory; this.coreReport = false;
this.description = description; this.useReport = useReport;
this.coreReport = false; this.reportSql = reportSql;
this.useReport = useReport; validate();
this.reportSql = reportSql; }
validate();
}
public Map<String, Object> update(final JsonCommand command) { public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>( final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(8);
8);
String paramName = "reportName"; String paramName = "reportName";
if (command.isChangeInStringParameterNamed(paramName, this.reportName)) { if (command.isChangeInStringParameterNamed(paramName, this.reportName)) {
final String newValue = command final String newValue = command.stringValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName); actualChanges.put(paramName, newValue);
actualChanges.put(paramName, newValue); this.reportName = StringUtils.defaultIfEmpty(newValue, null);
this.reportName = StringUtils.defaultIfEmpty(newValue, null); }
} paramName = "reportType";
paramName = "reportType"; if (command.isChangeInStringParameterNamed(paramName, this.reportType)) {
if (command.isChangeInStringParameterNamed(paramName, this.reportType)) { final String newValue = command.stringValueOfParameterNamed(paramName);
final String newValue = command actualChanges.put(paramName, newValue);
.stringValueOfParameterNamed(paramName); this.reportType = StringUtils.defaultIfEmpty(newValue, null);
actualChanges.put(paramName, newValue); }
this.reportType = StringUtils.defaultIfEmpty(newValue, null); paramName = "reportSubType";
} if (command.isChangeInStringParameterNamed(paramName, this.reportSubType)) {
paramName = "reportSubType"; final String newValue = command.stringValueOfParameterNamed(paramName);
if (command.isChangeInStringParameterNamed(paramName, actualChanges.put(paramName, newValue);
this.reportSubType)) { this.reportSubType = StringUtils.defaultIfEmpty(newValue, null);
final String newValue = command }
.stringValueOfParameterNamed(paramName); paramName = "reportCategory";
actualChanges.put(paramName, newValue); if (command.isChangeInStringParameterNamed(paramName, this.reportCategory)) {
this.reportSubType = StringUtils.defaultIfEmpty(newValue, null); final String newValue = command.stringValueOfParameterNamed(paramName);
} actualChanges.put(paramName, newValue);
paramName = "reportCategory"; this.reportCategory = StringUtils.defaultIfEmpty(newValue, null);
if (command.isChangeInStringParameterNamed(paramName, }
this.reportCategory)) { paramName = "description";
final String newValue = command if (command.isChangeInStringParameterNamed(paramName, this.description)) {
.stringValueOfParameterNamed(paramName); final String newValue = command.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportCategory = StringUtils.defaultIfEmpty(newValue, null); this.description = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "description"; paramName = "useReport";
if (command.isChangeInStringParameterNamed(paramName, this.description)) { if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) {
final String newValue = command final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName); actualChanges.put(paramName, newValue);
actualChanges.put(paramName, newValue); this.useReport = newValue;
this.description = StringUtils.defaultIfEmpty(newValue, null); }
} paramName = "reportSql";
paramName = "useReport"; if (command.isChangeInStringParameterNamed(paramName, this.reportSql)) {
if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) { final String newValue = command.stringValueOfParameterNamed(paramName);
final boolean newValue = command actualChanges.put(paramName, newValue);
.booleanPrimitiveValueOfParameterNamed(paramName); this.reportSql = StringUtils.defaultIfEmpty(newValue, null);
actualChanges.put(paramName, newValue);
this.useReport = newValue;
}
paramName = "reportSql";
if (command.isChangeInStringParameterNamed(paramName, this.reportSql)) {
final String newValue = command
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue);
this.reportSql = StringUtils.defaultIfEmpty(newValue, null);
}
final String reportParametersParamName = "reportParameters";
if (command.hasParameter(reportParametersParamName)) {
JsonArray jsonArray = command
.arrayOfParameterNamed(reportParametersParamName);
if (jsonArray != null) {
actualChanges.put(reportParametersParamName,
command.jsonFragment(reportParametersParamName));
}
}
validate();
if (!actualChanges.isEmpty()) {
if (isCoreReport()) {
for (final String key : actualChanges.keySet()) {
if (!(key.equals("useReport"))) {
throw new PlatformDataIntegrityException(
"error.msg.only.use.report.can.be.updated.for.core.report",
"Only the Use Report field can be updated for Core Reports",
key);
}
}
}
}
return actualChanges;
}
public boolean isCoreReport() {
return coreReport;
}
private void validate() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
dataValidationErrors).resource("report");
baseDataValidator.reset().parameter("reportName")
.value(this.reportName).notBlank().notExceedingLengthOf(100);
baseDataValidator
.reset()
.parameter("reportType")
.value(this.reportType)
.notBlank()
.isOneOfTheseValues(
new Object[] { "Table", "Pentaho", "Chart" });
baseDataValidator.reset().parameter("reportSubType")
.value(this.reportSubType).notExceedingLengthOf(20);
if (StringUtils.isNotBlank(this.reportType)) {
if (this.reportType.equals("Chart")) {
baseDataValidator
.reset()
.parameter("reportSubType")
.value(this.reportSubType)
.cantBeBlankWhenParameterProvidedIs("reportType",
this.reportType)
.isOneOfTheseValues(new Object[] { "Bar", "Pie" });
} else {
baseDataValidator
.reset()
.parameter("reportSubType")
.value(this.reportSubType)
.mustBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
}
}
baseDataValidator.reset().parameter("reportCategory")
.value(this.reportCategory).notExceedingLengthOf(45);
if (StringUtils.isNotBlank(this.reportType)) {
if ((this.reportType.equals("Table"))
|| (this.reportType.equals("Chart"))) {
baseDataValidator
.reset()
.parameter("reportSql")
.value(this.reportSql)
.cantBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
} else {
baseDataValidator
.reset()
.parameter("reportSql")
.value(this.reportSql)
.mustBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
}
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(
final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
}
public String getReportName() {
return reportName;
}
public Set<ReportParameterUsage> getReportParameterUsages() {
return reportParameterUsages;
}
public void setReportParameterUsages(
Set<ReportParameterUsage> reportParameterUsages) {
this.reportParameterUsages = reportParameterUsages;
}
public boolean update(
final Set<ReportParameterUsage> newReportParameterUsages) {
if (newReportParameterUsages == null)
return false;
boolean updated = false;
if (changeInReportParameters(newReportParameterUsages)) {
updated = true;
this.reportParameterUsages.clear();
this.reportParameterUsages.addAll(newReportParameterUsages);
}
return updated;
}
private boolean changeInReportParameters(
Set<ReportParameterUsage> newReportParameterUsages) {
if (!(this.reportParameterUsages.equals(newReportParameterUsages))) return true;
Map<Long, ReportParameterUsage> currentRPUs = new HashMap<Long, ReportParameterUsage>();
for (ReportParameterUsage rpu : this.reportParameterUsages) {
currentRPUs.put(rpu.getId(), rpu);
}
Map<Long, ReportParameterUsage> newRPUs = new HashMap<Long, ReportParameterUsage>();
for (ReportParameterUsage rpu : newReportParameterUsages) {
newRPUs.put(rpu.getId(), rpu);
}
ReportParameterUsage currentRPU = null;
ReportParameterUsage newRPU = null;
for (Long key : currentRPUs.keySet()) {
currentRPU = currentRPUs.get(key);
newRPU = newRPUs.get(key);
if (existingEntryChanged(currentRPU, newRPU)) return true;
} }
return false;
}
private boolean existingEntryChanged( final String reportParametersParamName = "reportParameters";
final ReportParameterUsage currentRPU, final ReportParameterUsage newRPU) { if (command.hasParameter(reportParametersParamName)) {
JsonArray jsonArray = command.arrayOfParameterNamed(reportParametersParamName);
if (jsonArray != null) {
actualChanges.put(reportParametersParamName, command.jsonFragment(reportParametersParamName));
}
}
if (!(currentRPU.getParameter().getId() validate();
.equals(newRPU.getParameter().getId())))
return true;
if ((currentRPU.getReportParameterName() == null) if (!actualChanges.isEmpty()) {
&& (newRPU.getReportParameterName() == null)) if (isCoreReport()) {
return false; for (final String key : actualChanges.keySet()) {
if (!(key.equals("useReport"))) { throw new PlatformDataIntegrityException(
"error.msg.only.use.report.can.be.updated.for.core.report",
"Only the Use Report field can be updated for Core Reports", key); }
}
}
}
if (!(currentRPU.getReportParameterName() return actualChanges;
.equals(newRPU.getReportParameterName()))) }
return true;
return false; public boolean isCoreReport() {
} return coreReport;
}
}
public ReportParameterUsage findReportParameterById(final Long reportParameterId) {
ReportParameterUsage reportParameterUsage = null;
for (ReportParameterUsage rpu : this.reportParameterUsages) {
if (rpu.hasIdOf(reportParameterId)) {
reportParameterUsage = rpu;
break;
}
}
return reportParameterUsage;
}
private void validate() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("report");
baseDataValidator.reset().parameter("reportName").value(this.reportName).notBlank().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("reportType").value(this.reportType).notBlank()
.isOneOfTheseValues(new Object[] { "Table", "Pentaho", "Chart" });
baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType).notExceedingLengthOf(20);
if (StringUtils.isNotBlank(this.reportType)) {
if (this.reportType.equals("Chart")) {
baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
.cantBeBlankWhenParameterProvidedIs("reportType", this.reportType)
.isOneOfTheseValues(new Object[] { "Bar", "Pie" });
} else {
baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
.mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
}
}
baseDataValidator.reset().parameter("reportCategory").value(this.reportCategory).notExceedingLengthOf(45);
if (StringUtils.isNotBlank(this.reportType)) {
if ((this.reportType.equals("Table")) || (this.reportType.equals("Chart"))) {
baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
.cantBeBlankWhenParameterProvidedIs("reportType", this.reportType);
} else {
baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
.mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
}
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public String getReportName() {
return reportName;
}
public boolean update(final Set<ReportParameterUsage> newReportParameterUsages) {
if (newReportParameterUsages == null) return false;
boolean updated = false;
if (changeInReportParameters(newReportParameterUsages)) {
updated = true;
this.reportParameterUsages.clear();
this.reportParameterUsages.addAll(newReportParameterUsages);
}
return updated;
}
private boolean changeInReportParameters(final Set<ReportParameterUsage> newReportParameterUsages) {
if (!(this.reportParameterUsages.equals(newReportParameterUsages))) return true;
return false;
}
}
@@ -14,8 +14,11 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "stretchy_parameter") @Table(name = "stretchy_parameter")
public class ReportParameter extends AbstractPersistable<Long> { public class ReportParameter extends AbstractPersistable<Long> {
protected ReportParameter() { protected ReportParameter() {
// //
} }
} public boolean hasIdOf(final Long id) {
return getId().equals(id);
}
}
@@ -11,63 +11,68 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity @Entity
@Table(name = "stretchy_report_parameter") @Table(name = "stretchy_report_parameter")
public class ReportParameterUsage extends AbstractPersistable<Long> { public final class ReportParameterUsage extends AbstractPersistable<Long> {
@SuppressWarnings("unused")
@ManyToOne(optional = false)
@JoinColumn(name = "report_id", nullable = false)
private Report report;
@SuppressWarnings("unused") @ManyToOne(optional = false)
@ManyToOne(optional = false) @JoinColumn(name = "report_id", nullable = false)
@JoinColumn(name = "parameter_id", nullable = false) private Report report;
private ReportParameter parameter;
@SuppressWarnings("unused") @ManyToOne(optional = false)
@Column(name = "report_parameter_name") @JoinColumn(name = "parameter_id", nullable = false)
private String reportParameterName; private ReportParameter parameter;
protected ReportParameterUsage() { @Column(name = "report_parameter_name")
// private String reportParameterName;
}
public ReportParameterUsage(final Report report, protected ReportParameterUsage() {
final ReportParameter parameter, final String reportParameterName) { //
this.report = report; }
this.parameter = parameter;
this.reportParameterName = reportParameterName;
}
public ReportParameterUsage(final ReportParameterUsage currentReportParameterUsage, final Report report,
final ReportParameter parameter, final String reportParameterName) {
this.setId(currentReportParameterUsage.getId());
this.report = report;
this.parameter = parameter;
this.reportParameterName = reportParameterName;
}
public void setReport(Report report) { public ReportParameterUsage(final Report report, final ReportParameter parameter, final String reportParameterName) {
this.report = report; this.report = report;
} this.parameter = parameter;
this.reportParameterName = reportParameterName;
}
public void setParameter(ReportParameter parameter) { @Override
this.parameter = parameter; public boolean equals(final Object obj) {
} if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) { return false; }
ReportParameterUsage rhs = (ReportParameterUsage) obj;
return new EqualsBuilder().appendSuper(super.equals(obj)) //
.append(this.getId(), rhs.getId()) //
.append(this.report.getId(), rhs.report.getId()) //
.append(this.parameter.getId(), rhs.parameter.getId()) //
.append(this.reportParameterName, rhs.reportParameterName) //
.isEquals();
}
public ReportParameter getParameter() { @Override
return parameter; public int hashCode() {
} return new HashCodeBuilder(3, 5) //
.append(this.getId()) //
.append(this.report.getId()) //
.append(this.parameter.getId()) //
.append(this.reportParameterName) //
.toHashCode();
}
public String getReportParameterName() { public boolean hasIdOf(final Long id) {
return reportParameterName; return getId().equals(id);
} }
public void setReportParameterName(String reportParameterName) { public boolean hasParameterIdOf(final Long parameterId) {
this.reportParameterName = reportParameterName; return this.parameter != null && this.parameter.hasIdOf(parameterId);
} }
} public void updateParameterName(final String parameterName) {
this.reportParameterName = parameterName;
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ReportParameterUsageRepository extends JpaRepository<ReportParameterUsage, Long>,
JpaSpecificationExecutor<ReportParameterUsage> {
// no added behaviour
}
@@ -13,6 +13,6 @@ public interface ReportWritePlatformService {
CommandProcessingResult createReport(JsonCommand command); CommandProcessingResult createReport(JsonCommand command);
CommandProcessingResult updateReport(Long reportId, JsonCommand command); CommandProcessingResult updateReport(Long reportId, JsonCommand command);
CommandProcessingResult deleteReport(Long reportId); CommandProcessingResult deleteReport(Long reportId);
} }
@@ -9,6 +9,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -17,6 +18,7 @@ import org.mifosplatform.infrastructure.dataqueries.domain.Report;
import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameter; import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameter;
import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameterRepository; import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameterRepository;
import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameterUsage; import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameterUsage;
import org.mifosplatform.infrastructure.dataqueries.domain.ReportParameterUsageRepository;
import org.mifosplatform.infrastructure.dataqueries.domain.ReportRepository; import org.mifosplatform.infrastructure.dataqueries.domain.ReportRepository;
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException; import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
import org.mifosplatform.infrastructure.dataqueries.exception.ReportParameterNotFoundException; import org.mifosplatform.infrastructure.dataqueries.exception.ReportParameterNotFoundException;
@@ -36,254 +38,204 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@Service @Service
public class ReportWritePlatformServiceImpl implements public class ReportWritePlatformServiceImpl implements ReportWritePlatformService {
ReportWritePlatformService {
private final static Logger logger = LoggerFactory private final static Logger logger = LoggerFactory.getLogger(ReportWritePlatformServiceImpl.class);
.getLogger(ReportWritePlatformServiceImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ReportCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final ReportCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final PermissionRepository permissionRepository; private final ReportRepository reportRepository;
private final ReportRepository reportRepository; private final ReportParameterUsageRepository reportParameterUsageRepository;
private final ReportParameterRepository reportParameterRepository; private final ReportParameterRepository reportParameterRepository;
private final PermissionRepository permissionRepository;
@Autowired @Autowired
public ReportWritePlatformServiceImpl( public ReportWritePlatformServiceImpl(final PlatformSecurityContext context,
final PlatformSecurityContext context, final ReportCommandFromApiJsonDeserializer fromApiJsonDeserializer, final ReportRepository reportRepository,
final ReportCommandFromApiJsonDeserializer fromApiJsonDeserializer, final ReportParameterRepository reportParameterRepository, final ReportParameterUsageRepository reportParameterUsageRepository,
final ReportRepository reportRepository, final PermissionRepository permissionRepository) {
final ReportParameterRepository reportParameterRepository, this.context = context;
final PermissionRepository permissionRepository) { this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.context = context; this.reportRepository = reportRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.reportParameterRepository = reportParameterRepository;
this.reportRepository = reportRepository; this.reportParameterUsageRepository = reportParameterUsageRepository;
this.reportParameterRepository = reportParameterRepository; this.permissionRepository = permissionRepository;
this.permissionRepository = permissionRepository; }
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult createReport(final JsonCommand command) { public CommandProcessingResult createReport(final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
this.fromApiJsonDeserializer.validate(command.json()); this.fromApiJsonDeserializer.validate(command.json());
final Report report = Report.fromJson(command); final Report report = Report.fromJson(command);
final Set<ReportParameterUsage> reportParameterUsages = assembleSetOfReportParameterUsages( final Set<ReportParameterUsage> reportParameterUsages = assembleSetOfReportParameterUsages(report, command);
report, command); report.update(reportParameterUsages);
if (reportParameterUsages != null) {
report.setReportParameterUsages(reportParameterUsages);
}
this.reportRepository.save(report);
final Permission permission = new Permission("report", this.reportRepository.save(report);
report.getReportName(), "READ");
this.permissionRepository.save(permission);
return new CommandProcessingResultBuilder() final Permission permission = new Permission("report", report.getReportName(), "READ");
.withCommandId(command.commandId()) this.permissionRepository.save(permission);
.withEntityId(report.getId()).build();
} catch (DataIntegrityViolationException dve) {
handleReportDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
@Transactional return new CommandProcessingResultBuilder() //
@Override .withCommandId(command.commandId()) //
public CommandProcessingResult updateReport(final Long reportId, .withEntityId(report.getId()) //
final JsonCommand command) { .build();
} catch (DataIntegrityViolationException dve) {
handleReportDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
try { @Transactional
context.authenticatedUser(); @Override
public CommandProcessingResult updateReport(final Long reportId, final JsonCommand command) {
this.fromApiJsonDeserializer.validate(command.json()); try {
context.authenticatedUser();
final Report report = this.reportRepository.findOne(reportId); this.fromApiJsonDeserializer.validate(command.json());
if (report == null) {
throw new ReportNotFoundException(reportId);
}
final Map<String, Object> changes = report.update(command); final Report report = this.reportRepository.findOne(reportId);
if (report == null) { throw new ReportNotFoundException(reportId); }
if (changes.containsKey("reportParameters")) { final Map<String, Object> changes = report.update(command);
final Set<ReportParameterUsage> reportParameterUsages = assembleSetOfReportParameterUsages(
report, command);
boolean updated = report.update(reportParameterUsages);
if (!updated) {
changes.remove("reportParameters");
}
}
if (!changes.isEmpty()) { if (changes.containsKey("reportParameters")) {
this.reportRepository.saveAndFlush(report); final Set<ReportParameterUsage> reportParameterUsages = assembleSetOfReportParameterUsages(report, command);
} boolean updated = report.update(reportParameterUsages);
if (!updated) {
changes.remove("reportParameters");
}
}
return new CommandProcessingResultBuilder() if (!changes.isEmpty()) {
.withCommandId(command.commandId()) this.reportRepository.saveAndFlush(report);
.withEntityId(report.getId()).with(changes).build(); }
} catch (DataIntegrityViolationException dve) {
handleReportDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
@Transactional return new CommandProcessingResultBuilder() //
@Override .withCommandId(command.commandId()) //
public CommandProcessingResult deleteReport(final Long reportId) { .withEntityId(report.getId()) //
.with(changes) //
.build();
} catch (DataIntegrityViolationException dve) {
handleReportDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
final Report report = this.reportRepository.findOne(reportId); @Transactional
if (report == null) { @Override
throw new ReportNotFoundException(reportId); public CommandProcessingResult deleteReport(final Long reportId) {
}
if (report.isCoreReport()) { final Report report = this.reportRepository.findOne(reportId);
throw new PlatformDataIntegrityException( if (report == null) { throw new ReportNotFoundException(reportId); }
"error.msg.cant.delete.core.report",
"Core Reports Can't be Deleted", "");
}
final Permission permission = this.permissionRepository if (report.isCoreReport()) {
.findOneByCode("READ" + "_" + report.getReportName()); //
if (permission == null) { throw new PlatformDataIntegrityException("error.msg.cant.delete.core.report", "Core Reports Can't be Deleted", "");
throw new PermissionNotFoundException("READ" + "_" }
+ report.getReportName());
}
this.reportRepository.delete(report); final Permission permission = this.permissionRepository.findOneByCode("READ" + "_" + report.getReportName());
this.permissionRepository.delete(permission); if (permission == null) { throw new PermissionNotFoundException("READ" + "_" + report.getReportName()); }
return new CommandProcessingResultBuilder().withEntityId(reportId) this.reportRepository.delete(report);
.build(); this.permissionRepository.delete(permission);
}
/* return new CommandProcessingResultBuilder() //
* Guaranteed to throw an exception no matter what the data integrity issue .withEntityId(reportId) //
* is. .build();
*/ }
private void handleReportDataIntegrityIssues(final JsonCommand command,
DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); /*
if (realCause.getMessage().contains("unq_report_name")) { * Guaranteed to throw an exception no matter what the data integrity issue
final String name = command * is.
.stringValueOfParameterNamed("reportName"); */
throw new PlatformDataIntegrityException( private void handleReportDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
"error.msg.report.duplicate.name", "A report with name '"
+ name + "' already exists", "name", name);
}
logger.error(dve.getMessage(), dve); Throwable realCause = dve.getMostSpecificCause();
throw new PlatformDataIntegrityException( if (realCause.getMessage().contains("unq_report_name")) {
"error.msg.report.unknown.data.integrity.issue", final String name = command.stringValueOfParameterNamed("reportName");
"Unknown data integrity issue with resource: " throw new PlatformDataIntegrityException("error.msg.report.duplicate.name", "A report with name '" + name + "' already exists",
+ realCause.getMessage()); "name", name);
} }
private Set<ReportParameterUsage> assembleSetOfReportParameterUsages( logger.error(dve.getMessage(), dve);
final Report report, final JsonCommand command) { throw new PlatformDataIntegrityException("error.msg.report.unknown.data.integrity.issue",
if (report == null) { "Unknown data integrity issue with resource: " + realCause.getMessage());
throw new PlatformDataIntegrityException("system.error", }
"report parameter is null; ");
}
if (command.parameterExists("reportParameters")) { private Set<ReportParameterUsage> assembleSetOfReportParameterUsages(final Report report, final JsonCommand command) {
Set<ReportParameterUsage> reportParameterUsages = new HashSet<ReportParameterUsage>();
JsonArray reportParametersArray = command
.arrayOfParameterNamed("reportParameters");
if (reportParametersArray != null) {
for (int i = 0; i < reportParametersArray.size(); i++) {
final JsonObject jsonObject = reportParametersArray.get(i) Set<ReportParameterUsage> reportParameterUsages = null;
.getAsJsonObject();
Long id = null;
ReportParameter parameter = null;
String reportParameterName = null;
if (jsonObject.has("parameterId")) { if (command.parameterExists("reportParameters")) {
final Long parameterId = jsonObject.get("parameterId") JsonArray reportParametersArray = command.arrayOfParameterNamed("reportParameters");
.getAsLong(); if (reportParametersArray != null) {
parameter = this.reportParameterRepository
.findOne(parameterId);
if (parameter == null) {
throw new ReportParameterNotFoundException(
parameterId);
}
} else {
throw new PlatformDataIntegrityException(
"error.msg.parameter.id.mandatory.in.report.parameter",
"parameterId column is mandatory in Report Parameter Entry");
}
if (jsonObject.has("reportParameterName")) { reportParameterUsages = new HashSet<ReportParameterUsage>();
reportParameterName = jsonObject.get(
"reportParameterName").getAsString();
}
if (jsonObject.has("id")) { for (int i = 0; i < reportParametersArray.size(); i++) {
final String idStr = jsonObject.get("id").getAsString();
if (!(idStr.equals("")))
id = Long.parseLong(idStr);
}
ReportParameterUsage reportParameterUsage = null; final JsonObject jsonObject = reportParametersArray.get(i).getAsJsonObject();
if (id == null) {
reportParameterUsage = new ReportParameterUsage(report,
parameter, reportParameterName);
} else {
ReportParameterUsage currentReportParameterUsage = rpuById(
report, id);
if (existingEntryChanged(currentReportParameterUsage, Long id = null;
parameter.getId(), reportParameterName)) { ReportParameterUsage reportParameterUsageItem = null;
reportParameterUsage = new ReportParameterUsage( ReportParameter reportParameter = null;
currentReportParameterUsage, report, String reportParameterName = null;
parameter, reportParameterName);
} else {
reportParameterUsage = currentReportParameterUsage;
}
}
reportParameterUsages.add(reportParameterUsage); if (jsonObject.has("id")) {
} final String idStr = jsonObject.get("id").getAsString();
return reportParameterUsages; if (StringUtils.isNotBlank(idStr)) {
} else id = Long.parseLong(idStr);
return null; }
} else }
return null;
}
private boolean existingEntryChanged( if (id != null) {
final ReportParameterUsage currentReportParameterUsage, // existing report parameter usage
final Long parameterId, final String reportParameterName) { reportParameterUsageItem = this.reportParameterUsageRepository.findOne(id);
if (reportParameterUsageItem == null) { throw new ReportParameterNotFoundException(id); }
if (!(currentReportParameterUsage.getParameter().getId() // check parameter
.equals(parameterId))) if (jsonObject.has("parameterId")) {
return true; final Long parameterId = jsonObject.get("parameterId").getAsLong();
reportParameter = this.reportParameterRepository.findOne(parameterId);
if (reportParameter == null || !reportParameterUsageItem.hasParameterIdOf(parameterId)) {
//
throw new ReportParameterNotFoundException(parameterId);
}
}
if ((reportParameterName == null) if (jsonObject.has("reportParameterName")) {
&& (currentReportParameterUsage.getReportParameterName() == null)) reportParameterName = jsonObject.get("reportParameterName").getAsString();
return false; reportParameterUsageItem.updateParameterName(reportParameterName);
}
} else {
// new report parameter usage
if (jsonObject.has("parameterId")) {
final Long parameterId = jsonObject.get("parameterId").getAsLong();
reportParameter = this.reportParameterRepository.findOne(parameterId);
if (reportParameter == null) { throw new ReportParameterNotFoundException(parameterId); }
} else {
throw new PlatformDataIntegrityException("error.msg.parameter.id.mandatory.in.report.parameter",
"parameterId column is mandatory in Report Parameter Entry");
}
if (!(currentReportParameterUsage.getReportParameterName() if (jsonObject.has("reportParameterName")) {
.equals(reportParameterName))) reportParameterName = jsonObject.get("reportParameterName").getAsString();
return true; }
return false; reportParameterUsageItem = new ReportParameterUsage(report, reportParameter, reportParameterName);
} }
private ReportParameterUsage rpuById(final Report report, final Long id) { reportParameterUsages.add(reportParameterUsageItem);
}
}
}
for (ReportParameterUsage rpu : report.getReportParameterUsages()) { return reportParameterUsages;
if (rpu.getId().equals(id)) }
return rpu;
}
throw new PlatformDataIntegrityException(
"error.msg.supplied.parameter.id.doesnt.exist",
"Supplied parameterId column doesn't Exist", id);
}
} }