package org.akaza.openclinica.view.form;
import org.akaza.openclinica.bean.submit.DisplayItemBean;
import org.akaza.openclinica.bean.submit.DisplayItemGroupBean;
import org.akaza.openclinica.bean.submit.DisplaySectionBean;
import org.akaza.openclinica.bean.submit.ItemDataBean;
import org.akaza.openclinica.bean.submit.SectionBean;
import org.akaza.openclinica.control.managestudy.BeanFactory;
import org.jdom.Element;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedMap;
/**
* This is a Decorator design pattern for the ViewBuilderUtil Class. It adds
* printing related functionality to that class.
*/
public class ViewBuilderPrintDecorator {
private final ViewBuilderUtil viewBuilderUtil;
public ViewBuilderPrintDecorator() {
this.viewBuilderUtil = new ViewBuilderUtil();
}
/**
* Create the div element for showing titles, page number, and instructions
*
* @param divRoot
* The root div element that will contain this new div element.
* @param sectionBean
* The SectionBean that encompasses the CRF title and
* instructions.
* @param pageNumber
* The page number for the printed form.
* @param changeForInternetExplorer
* A boolean value indicating that Internet Explorer is the
* browser. In this case, the div elements for titles should not
* have float properties set.
*/
public void showTitles(Element divRoot, SectionBean sectionBean, int pageNumber, boolean changeForInternetExplorer) {
/*
* <div id="section_page" style="float:left;border-bottom:thin solid
* gray"> <div id="section" style="float:left;">SECTION: </div> <div
* id="page" style="float:right;">Page: 1 </div> <div id="instructions"
* style="float:left;clear:both">Instructions: </div>
*
* </div>
*/
Element titleDiv = new Element("div");
titleDiv.setAttribute("id", ("section_page" + pageNumber));
titleDiv.setAttribute("class", "section_page");
if (changeForInternetExplorer) {
titleDiv.setAttribute("style", "float:none");
}
divRoot.addContent(titleDiv);
Element secDiv = new Element("div");
secDiv.setAttribute("id", ("section" + pageNumber));
secDiv.setAttribute("class", "section");
if (changeForInternetExplorer) {
secDiv.setAttribute("style", "float:none");
}
// Section: should be in bold
Element strong = new Element("strong");
strong.addContent("Section: ");
secDiv.addContent(strong);
secDiv.addContent(sectionBean.getTitle());
titleDiv.addContent(secDiv);
Element pageDiv = new Element("div");
pageDiv.setAttribute("id", ("page" + pageNumber));
// pageDiv.setAttribute("class", "page");
if (changeForInternetExplorer) {
pageDiv.setAttribute("style", "float:none");
}
Element strong2 = new Element("strong");
strong2.addContent("Page: ");
pageDiv.addContent(strong2);
pageDiv.addContent("" + pageNumber);
titleDiv.addContent(pageDiv);
// Instructions for the section
Element instructDiv = new Element("div");
instructDiv.setAttribute("id", ("instructions" + pageNumber));
instructDiv.setAttribute("class", "instructions");
if (changeForInternetExplorer) {
instructDiv.setAttribute("style", "float:none");
}
Element strong3 = new Element("strong");
strong3.addContent("Instructions: ");
instructDiv.addContent(strong3);
instructDiv.addContent(sectionBean.getInstructions());
titleDiv.addContent(instructDiv);
}
public boolean hasResponseLayout(List<DisplayItemBean> displayBeans) {
if (displayBeans == null || displayBeans.isEmpty()) {
return false;
}
synchronized (this.viewBuilderUtil) {
return viewBuilderUtil.hasResponseLayout(displayBeans);
}
}
public Element setClassNames(Element styledElement) {
synchronized (this.viewBuilderUtil) {
return viewBuilderUtil.setClassNames(styledElement);
}
}
public void addRemoveRowControl(Element row, String repeatParentId) {
synchronized (this.viewBuilderUtil) {
viewBuilderUtil.addRemoveRowControl(row, repeatParentId, false);
}
}
public void createAddRowControl(Element tbody, String repeatParentId, int columnNumber) {
synchronized (this.viewBuilderUtil) {
viewBuilderUtil.createAddRowControl(tbody, repeatParentId, columnNumber, false);
}
}
public List generatePersistentMatrixRows(SortedMap<Integer, List<ItemDataBean>> sortedDataMap, List<DisplayItemBean> rowContentBeans,
int tabIndex, String repeatParentId, boolean hasDiscrepancyMgt, boolean forPrinting, int maxColRows) {
synchronized (this.viewBuilderUtil) {
return viewBuilderUtil.generatePersistentMatrixRowsNew(sortedDataMap, rowContentBeans, tabIndex, repeatParentId, hasDiscrepancyMgt, forPrinting, false, maxColRows);
}
}
public int calcNumberofColumns(DisplayItemGroupBean displayGroup) {
synchronized (this.viewBuilderUtil) {
return viewBuilderUtil.calcNumberofColumns(displayGroup);
}
}
/**
* This method determines whether a CRF section contains a group-type table
* with three or more columns, for the purpose of printing CRFs.
*
* @param displaySectionBean
* The DisplaySectionBean representing the section.
* @return true if the sections contains a group-type table that has three
* or more columns.
*/
public boolean hasThreePlusColumns(DisplaySectionBean displaySectionBean) {
if (displaySectionBean == null)
return false;
List<DisplayItemBean> currentDisplayItems = null;
for (DisplayItemGroupBean displayItemGroup : displaySectionBean.getDisplayFormGroups()) {
// Ignore forms that are not group-type tables
if (displayItemGroup.getItemGroupBean().getName().equalsIgnoreCase(BeanFactory.UNGROUPED)) {
continue;
}
currentDisplayItems = displayItemGroup.getItems();
// If the group table's items size is greater than 3, then the table
// has a
// group table that exceeds three columns
if (currentDisplayItems.size() > 3) {
return true;
}
}
return false;
}
/**
*
* @param groupBeans
* @return
*/
public List<DisplayItemGroupBean> reduceColumnsGroupTables(List<DisplayItemGroupBean> groupBeans) {
if (groupBeans == null || groupBeans.size() == 0)
return groupBeans;
List<DisplayItemGroupBean> newGroupBeans = new ArrayList<DisplayItemGroupBean>();
// the ordinal of the first group table that is being broken up into
// multiple columns
// we then have to change the ordinals of all of the group beans that
// follow this one.
// See below
int startOrdinal = 0;
int i = 0;
for (DisplayItemGroupBean existingDisplayBean : groupBeans) {
// If the group table has more than three columns and does not have
// a name of "ungrouped" then break the bean up into single column
// beans
if (existingDisplayBean.getItems().size() > 3 && !BeanFactory.UNGROUPED.equalsIgnoreCase(existingDisplayBean.getItemGroupBean().getName())) {
startOrdinal = existingDisplayBean.getOrdinal();
// increment the ordinals of the other beans to make up for this
// one
// this.incrementDisplayBeanOrdinals(groupBeans, startOrdinal, existingDisplayBean.getItems().size() - 1);
newGroupBeans.addAll(splitUpGroupBeanIntoSingleColumns(existingDisplayBean));
} else {
// otherwise, add the existing bean to the List
newGroupBeans.add(existingDisplayBean);
}
}
// Now sort the new beans on their ordinal
Collections.sort(newGroupBeans);
return newGroupBeans;
}
/**
* This method takes a List of DisplayItemGroupBeans, and increases the
* ordinals of some of the beans, to compensate for the fact that previous
* DisplayItemGroupBeans in the List have been split up into single-column
* beans with new ordinals. Therefore, the DisplayItemGroupBeans following
* them on the section have to have their ordinals (specifying their
* position on the CRF section) incremented, so that they keep their proper
* position on the CRF.
*
* @param displayItemGroupBeans
* A List of DisplayItemGroupBeans, representing group tables on
* a CRF section.
* @param startOrdinal
* The ordinal of the DisplayItemGroupBean that is split up into
* multiple DisplayItemGroupBeans.
* @param incrementByNumber
* The number by which the following DisplayItemGroupBeans have
* to increment their ordinals. This number is equal to split-up
* DisplayItemGroupBean.getItems().size() - 1 .
*/
public void incrementDisplayBeanOrdinals(List<DisplayItemGroupBean> displayItemGroupBeans, int startOrdinal, int incrementByNumber) {
int tempOrdinal = 0;
for (DisplayItemGroupBean displayItemGroupBean : displayItemGroupBeans) {
tempOrdinal = displayItemGroupBean.getOrdinal();
if (tempOrdinal <= startOrdinal)
continue;
displayItemGroupBean.setOrdinal(displayItemGroupBean.getOrdinal() + incrementByNumber);
}
}
public List<DisplayItemGroupBean> splitUpGroupBeanIntoSingleColumns(DisplayItemGroupBean existingBean) {
List<DisplayItemGroupBean> newDisplayBeans = new ArrayList<DisplayItemGroupBean>();
int ordinal = existingBean.getOrdinal();
DisplayItemGroupBean cloneDisplayBean = cloneDisplayItemGroupBean(existingBean, existingBean.getItems().get(0), ordinal);
if (existingBean == null) {
return newDisplayBeans;
}
// Create a DisplayItemGroupBean for every display item bean
for (int i=1; i< existingBean.getItems().size(); i++) {
DisplayItemBean displayItemBean = existingBean.getItems().get(i);
if(i%3==0){
ordinal++;
newDisplayBeans.add(cloneDisplayBean);
cloneDisplayBean = cloneDisplayItemGroupBean(existingBean, displayItemBean, ordinal);
}else{
cloneDisplayBean.getItems().add(displayItemBean);
}
}
newDisplayBeans.add(cloneDisplayBean);
return newDisplayBeans;
}
public DisplayItemGroupBean cloneDisplayItemGroupBean(DisplayItemGroupBean clonedGroupBean, DisplayItemBean displayItemBean,int ordinal) {
DisplayItemGroupBean newGroupBean = new DisplayItemGroupBean();
if (clonedGroupBean == null)
return newGroupBean;
newGroupBean.setGroupMetaBean(clonedGroupBean.getGroupMetaBean());
newGroupBean.setItemGroupBean(clonedGroupBean.getItemGroupBean());
newGroupBean.getItems().add(displayItemBean);
newGroupBean.setOrdinal(ordinal);
return newGroupBean;
}
}