Skip to content
This repository has been archived by the owner on Jan 21, 2021. It is now read-only.

Commit

Permalink
Modify: Add javadoc for report package.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bitaron committed Sep 10, 2017
1 parent a206423 commit abd05c6
Show file tree
Hide file tree
Showing 6 changed files with 451 additions and 322 deletions.
Original file line number Diff line number Diff line change
@@ -1,39 +1,67 @@
package org.opensrp.register.mcare.report.mis1;


import org.opensrp.register.mcare.domain.Members;
import org.opensrp.register.mcare.report.mis1.familyPlanning.FamilyPlanningReport;
import org.opensrp.register.mcare.report.mis1.maternityCare.MaternityCareReport;

import java.util.List;

/**
* Top level class for calculating MIS1Report.
* Client init an object of this class using the targeted member list.
* <br>
* <b>For developers</b>
* <br>
* Targeted member list is looped through once in this top level class. All the internal.
* <i>{@link org.opensrp.register.mcare.report.mis1.Report}</i> object operate on single <i>{@link org.opensrp.register.mcare.domain.Members}</i> object.
* <br>
* TODO: <br>
* 1. Go through the code to understand underlying desing patterns. <br>
* 2. Don't use raw strings. Update <i>{@link org.opensrp.register.mcare.domain.Members}</i> class with key value. e.g: {@link org.opensrp.register.mcare.domain.Members.VaccineDose}. <br>
* 3. Some report calculators are done partially e.g:{@link org.opensrp.register.mcare.report.mis1.maternityCare.ANCReportCalculator}. Others calculation can be done in same way. <br>
* <br>
* For a general understanding, this class represents the complete page of SRS with all the table. Every Report object {@link FamilyPlanningReport} is an table of SRS.
* Every Report calculator object can be thought of an row of the table {@link org.opensrp.register.mcare.report.mis1.familyPlanning.birthControlMethdoUsagesCalculation.CondomMethodUsagesCalculator}, {@link org.opensrp.register.mcare.report.mis1.maternityCare.TTDoseReportCalculator}.
* <br>
*
* @see <a href="http://doc.mpower-social.com:8080/share/page/document-details?nodeRef=workspace://SpacesStore/bb7b37bd-0d5a-4813-9903-33dce944b165">MIS1 Report SRS.</a>
* <br>
* @see <a href="https://go.gliffy.com/go/publish/12216901">Class diagram</a>
*/
public class MIS1Report {
private String unionName;
private List<Members> membersList;
private FamilyPlanningReport familyPlanningReport;
private MaternityCareReport maternityCareReport;


public MIS1Report(String unionName, List<Members> membersList, long startDateTime, long endDateTime) {
this.unionName = unionName;
this.membersList = membersList;
this.familyPlanningReport = new FamilyPlanningReport(startDateTime, endDateTime);
this.maternityCareReport = new MaternityCareReport(startDateTime, endDateTime);
this.calculateReport();
}

public FamilyPlanningReport getFamilyPlanningReport() {
return familyPlanningReport;
}

public MaternityCareReport getMaternityCareReport() {
return maternityCareReport;
}

private void calculateReport() {
for (Members member : membersList) {
familyPlanningReport.calculate(member);
maternityCareReport.calculate(member);
}
}

private String unionName;

private List<Members> membersList;

private FamilyPlanningReport familyPlanningReport;

private MaternityCareReport maternityCareReport;

public MIS1Report(String unionName, List<Members> membersList, long startDateTime, long endDateTime) {
this.unionName = unionName;
this.membersList = membersList;
this.familyPlanningReport = new FamilyPlanningReport(startDateTime, endDateTime);
this.maternityCareReport = new MaternityCareReport(startDateTime, endDateTime);
this.calculateReport();
}

public FamilyPlanningReport getFamilyPlanningReport() {
return familyPlanningReport;
}

public MaternityCareReport getMaternityCareReport() {
return maternityCareReport;
}

/**
* This function calls all member reports <i>calculate</i> method using single member.
* <b>Should be called inside constructor.</b>
*/
private void calculateReport() {
for (Members member : membersList) {
familyPlanningReport.calculate(member);
maternityCareReport.calculate(member);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.opensrp.register.mcare.report.mis1;


import org.opensrp.register.mcare.domain.Members;

import java.lang.reflect.Constructor;
Expand All @@ -9,58 +8,98 @@
import java.lang.reflect.Method;
import java.util.Calendar;

/**
* Base class for Report. Every report should extends this class.
*/
public abstract class Report {

public Report(long startDateTime, long endDateTime) {
this.initCalculators(startDateTime, endDateTime);
}

protected abstract void calculate(Members member);
public Report(long startDateTime, long endDateTime) {
this.initCalculators(startDateTime, endDateTime);
}

protected abstract void initCalculators(long startDateTime, long endDateTime);
/**
* Concrete class should implement this method to calculate their desired method to based on current
* Member.
* e.g: whether current member is pregnant or not.
*
* @param member
*/
protected abstract void calculate(Members member);

/**
* Concrete class should implement this method to init their internal report calculator objects.
*
* @param startDateTime
* @param endDateTime
*/
protected abstract void initCalculators(long startDateTime, long endDateTime);

protected void useReflectionToDynamicallyInitAllMemberOf(Class reportClass, long startDateTime, long endDateTime) {
Field[] fields = reportClass.getDeclaredFields();
for (Field field : fields) {
if(!field.isSynthetic()) {
field.setAccessible(true);
try {
Class classOfFiled = Class.forName(field.getType().getName());
Constructor constructor = classOfFiled.getConstructor(long.class, long.class);
field.set(this, constructor.newInstance(startDateTime, endDateTime));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
/**
* This function uses reflection to init all the internal report calculator objects of a report.
* It assumes that an `Report` object only has `ReportCalculator` objects.
* TODO: Remove dependency (It assumes that an `Report` object only has `ReportCalculator` objects.)
*
* @param reportClass
* @param startDateTime
* @param endDateTime
*/
protected void useReflectionToDynamicallyInitAllMemberOf(Class reportClass, long startDateTime, long endDateTime) {
Field[] fields = reportClass.getDeclaredFields();
for (Field field : fields) {
if (!field.isSynthetic()) {
field.setAccessible(true);
try {
Class classOfFiled = Class.forName(field.getType().getName());
Constructor constructor = classOfFiled.getConstructor(long.class, long.class);
field.set(this, constructor.newInstance(startDateTime, endDateTime));
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}

protected void useReflectionToDynamicallyCallCalculateMethodOnAllMemberOf(Class reportClass, Members member) {
Field[] fields = reportClass.getDeclaredFields();
for (Field field : fields) {
if(!field.isSynthetic()) {
field.setAccessible(true);
try {
Object fieldValue = field.get(this);
Method calculate = fieldValue.getClass().getMethod("calculate", Members.class);
calculate.invoke(fieldValue, member);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
/**
* This function uses reflection to call `calculate` method of all the internal report calculator objects of a report.
* It assumes that an `Report` object only has `ReportCalculator` objects.
* TODO: Remove dependency (It assumes that an `Report` object only has `ReportCalculator` objects.)
*
* @param reportClass
* @param member
*/
protected void useReflectionToDynamicallyCallCalculateMethodOnAllMemberOf(Class reportClass, Members member) {
Field[] fields = reportClass.getDeclaredFields();
for (Field field : fields) {
if (!field.isSynthetic()) {
field.setAccessible(true);
try {
Object fieldValue = field.get(this);
Method calculate = fieldValue.getClass().getMethod("calculate", Members.class);
calculate.invoke(fieldValue, member);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
package org.opensrp.register.mcare.report.mis1;


import org.opensrp.register.mcare.domain.Members;

import java.util.Map;

/**
* Base abstract class for report calculation. Every report calculator should extends this class.
*/
public abstract class ReportCalculator {
protected long startDateTime;
protected long endDateTime;

public ReportCalculator(long startDateTime, long endDateTime) {
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
}

public abstract void calculate(Members member);

protected boolean withInStartAndEndTime(Map<String, String> visitData) {
if(visitData.containsKey(Members.CLIENT_VERSION_KEY)) {
long clientVersion = Long.parseLong(visitData.get(Members.CLIENT_VERSION_KEY));
if(clientVersion >= startDateTime && clientVersion <= endDateTime) {
return true;
}
}
return false;
}

protected long startDateTime;

protected long endDateTime;

public ReportCalculator(long startDateTime, long endDateTime) {
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
}

/**
* Concrete class should implement this method to calculate their desired method to based on current
* Member.
* e.g: whether current member is pregnant or not.
*
* @param member
*/
public abstract void calculate(Members member);

/**
* Check if given map visit data(PSRF, ANC, PNC) within start and end time.
*
* @param visitData
* @return
*/
protected boolean withInStartAndEndTime(Map<String, String> visitData) {
if (visitData.containsKey(Members.CLIENT_VERSION_KEY)) {
long clientVersion = Long.parseLong(visitData.get(Members.CLIENT_VERSION_KEY));
if (clientVersion >= startDateTime && clientVersion <= endDateTime) {
return true;
}
}
return false;
}
}
Loading

0 comments on commit abd05c6

Please sign in to comment.