public class UIWorkbook extends UIComponentBase implements FacesAjaxComponent {

	public static final String COMPONENT_TYPE = "biz.webgate.dominoext.poi.Workbook"; //$NON-NLS-1$
	public static final String COMPONENT_FAMILY = "biz.webgate.dominoext.poi.Workbook"; //$NON-NLS-1$
	public static final String RENDERER_TYPE = "biz.webgate.dominoext.poi.Workbook"; //$NON-NLS-1$

	private List<Spreadsheet> m_Spreadsheets;
	private String m_pathInfo;
	private String m_DownloadFileName;
	private ITemplateSource m_TemplateSource;
	private MethodBinding m_PostGenerationProcess;
	private boolean m_UseStreamingModel = false;

	public boolean isUseStreamingModel() {
		return m_UseStreamingModel;
	}

	public void setUseStreamingModel(boolean useStreamingModel) {
		m_UseStreamingModel = useStreamingModel;
	}

	public UIWorkbook() {

		super();
		setRendererType(RENDERER_TYPE);
	}

	public List<Spreadsheet> getSpreadsheets() {
		return m_Spreadsheets;
	}

	public void setSpreadsheets(List<Spreadsheet> tables) {
		m_Spreadsheets = tables;
	}

	public void addSpreadsheet(Spreadsheet tbCurrent) {
		if (m_Spreadsheets == null) {
			m_Spreadsheets = new ArrayList<>();
		}
		m_Spreadsheets.add(tbCurrent);
	}

	public String getPathInfo() {
		if (null != m_pathInfo) {
			return m_pathInfo;
		}
		ValueBinding _vb = getValueBinding("pathInfo"); //$NON-NLS-1$
		if (_vb != null) {
			return (java.lang.String) _vb.getValue(FacesContext.getCurrentInstance());
		} else {
			return null;
		}
	}

	public void setPathInfo(String linkName) {
		m_pathInfo = linkName;
	}

	public String getDownloadFileName() {
		if (null != m_DownloadFileName) {
			return m_DownloadFileName;
		}
		ValueBinding _vb = getValueBinding("downloadFileName"); //$NON-NLS-1$
		if (_vb != null) {
			return (java.lang.String) _vb.getValue(FacesContext.getCurrentInstance());
		} else {
			return null;
		}
	}

	public void setDownloadFileName(String downloadFileName) {
		m_DownloadFileName = downloadFileName;
	}

	public ITemplateSource getTemplateSource() {
		return m_TemplateSource;
	}

	public void setTemplateSource(ITemplateSource templateSource) {
		m_TemplateSource = templateSource;
	}

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}

	@Override
	public boolean handles(FacesContext context) {
		String reqPathInfo = context.getExternalContext().getRequestPathInfo();
		if (StringUtil.isNotEmpty(reqPathInfo)) {
			String pathInfo = getPathInfo();
			if (StringUtil.isEmpty(pathInfo)) {
				return false;
			}
			if (!pathInfo.startsWith("/")) {
				pathInfo = "/" + pathInfo;
			}
			if (!pathInfo.endsWith("/")) {
				pathInfo += "/";
			}
			if (!reqPathInfo.startsWith("/")) {
				reqPathInfo = "/" + reqPathInfo;
			}
			if (!reqPathInfo.endsWith("/")) {
				reqPathInfo += "/";
			}
			if (reqPathInfo.startsWith(pathInfo)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void processAjaxRequest(FacesContext context) throws IOException {
		WorkbookProcessor.INSTANCE.processCall(context, this, false, null);
	}

	public MethodBinding getPostGenerationProcess() {
		return m_PostGenerationProcess;
	}

	public void setPostGenerationProcess(MethodBinding postGenerationProcess) {
		m_PostGenerationProcess = postGenerationProcess;
	}

	// SAVING AND RESTORING
	@Override
	public Object saveState(FacesContext context) {
		try {
			Object[] state = new Object[7];
			state[0] = super.saveState(context);
			state[1] = m_DownloadFileName;
			state[2] = m_pathInfo;
			state[3] = FacesUtil.objectToSerializable(context, m_TemplateSource);
			state[4] = StateHolderUtil.saveList(context, m_Spreadsheets);
			state[5] = StateHolderUtil.saveMethodBinding(context, m_PostGenerationProcess);
			state[6] = Boolean.valueOf(m_UseStreamingModel);
			return state;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void restoreState(FacesContext context, Object value) {
		Object[] state = (Object[]) value;
		super.restoreState(context, state[0]);
		m_DownloadFileName = (String) state[1];
		m_pathInfo = (String) state[2];
		m_TemplateSource = (ITemplateSource) FacesUtil.objectFromSerializable(context, this, state[3]);
		m_Spreadsheets = StateHolderUtil.restoreList(context, this, state[4]);
		m_PostGenerationProcess = StateHolderUtil.restoreMethodBinding(context, this, state[5]);
		m_UseStreamingModel = ((Boolean) state[6]);
	}

	public boolean postGenerationProcess(FacesContext context, Workbook wbCurrent) {
		if (m_PostGenerationProcess != null) {
			Object[] params = null;
			if (m_PostGenerationProcess instanceof MethodBindingEx) {
				params = new Object[] { wbCurrent };
				((MethodBindingEx) m_PostGenerationProcess).setComponent(this);
				((MethodBindingEx) m_PostGenerationProcess).setParamNames(s_postGenParamNames);
			}

			doPostGenerationProcessPrivileged(context, params);

			/*
			 * if (FacesUtil.isCancelled(m_PostGenerationProcess.invoke(context,
			 * params))) { return false; }
			 */
			return true;
		}
		return true;
	}

	public void doPostGenerationProcessPrivileged(final FacesContext context, final Object[] params) {
		try {
			AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
				m_PostGenerationProcess.invoke(context, params);
				return null;
			});
		} catch (PrivilegedActionException e) {
			e.printStackTrace();
		}
	}

	private static final String[] s_postGenParamNames = { "workbook" }; // $NON-NLS-1$

} public interface ITemplateSource {

	public InputStream getFileStream();

	public int accessTemplate();

	public void cleanUP();
} public class Data2ColumnExporter extends AbstractDataExporter implements
		IListDataExporter {

	List<RowDefinition> m_Rows;
	Integer m_StartColumn;

	public int getStartColumn() {
		if (m_StartColumn != null) {
			return m_StartColumn;
		}
		ValueBinding vb = getValueBinding("startColumn");
		if (vb != null) {
			Integer intValue = (Integer) vb.getValue(getFacesContext());
			if (intValue != null)
				return intValue;
		}
		return 0;
	}

	public void setStartColumn(int startColumn) {
		m_StartColumn = startColumn;
	}

	public void addRow(RowDefinition rdCurrent) {
		if (m_Rows == null) {
			m_Rows = new ArrayList<>();
		}
		m_Rows.add(rdCurrent);
	}

	public List<RowDefinition> getRows() {
		return m_Rows;
	}

	public void setRows(List<RowDefinition> rows) {
		m_Rows = rows;
	}

	@Override
	public Object saveState(FacesContext context) {
		Object[] state = new Object[3];
		state[0] = super.saveState(context);
		state[1] = m_StartColumn;
		state[2] = StateHolderUtil.saveList(getFacesContext(), m_Rows);
		return state;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_StartColumn = (Integer) state[1];
		m_Rows = StateHolderUtil.restoreList(getFacesContext(), getComponent(),
				state[2]);

	}

} public class Data2RowExporter extends AbstractDataExporter implements
		IListDataExporter {
	private Integer m_StartRow;
	private List<ColumnDefinition> m_Columns;

	public int getStartRow() {
		if (m_StartRow != null) {
			return m_StartRow;
		}
		ValueBinding vb = getValueBinding("startRow");
		if (vb != null) {
			Integer intValue = (Integer) vb.getValue(getFacesContext());
			if (intValue != null)
				return intValue;
		}
		return 0;

	}

	public void setStartRow(int startRow) {
		m_StartRow = startRow;
	}

	public List<ColumnDefinition> getColumns() {
		return m_Columns;
	}

	public void setColumns(List<ColumnDefinition> columns) {
		m_Columns = columns;
	}

	public void addColumn(ColumnDefinition cdCurrent) {
		if (m_Columns == null) {
			m_Columns = new ArrayList<>();
		}
		m_Columns.add(cdCurrent);
	}

	@Override
	public Object saveState(FacesContext context) {
		Object[] state = new Object[5];
		state[0] = super.saveState(context);
		state[1] = m_StartRow;
		state[2] = StateHolderUtil.saveList(context, m_Columns);
		return state;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_StartRow = (Integer) state[1];
		m_Columns = StateHolderUtil.restoreList(context, getComponent(),
				state[2]);

	}
} public interface IListDataExporter {
	public IExportSource getDataSource();

} public class Spreadsheet extends ValueBindingObjectImpl {

	private String m_Name;
	private Boolean m_Create;
	private List<IListDataExporter> m_ExportDefinition;
	private List<ICellValue> m_CellValues;

	public String getName() {
		if (m_Name != null) {
			return m_Name;
		}
		ValueBinding vb = getValueBinding("name");
		if (vb != null) {
			return (String) vb.getValue(getFacesContext());
		}
		return null;
	}

	public void setName(String name) {
		m_Name = name;
	}

	public boolean isCreate() {
		if (m_Create != null) {
			return m_Create;
		}
		ValueBinding vb = getValueBinding("create");
		if (vb != null) {
			Boolean blValue = (Boolean) vb.getValue(getFacesContext());
			if (blValue != null) {
				return blValue;
			}
		}
		return false;
	}

	public void setCreate(boolean create) {
		m_Create = create;
	}

	public List<IListDataExporter> getExportDefinitions() {
		return m_ExportDefinition;
	}

	public void setExportDefinitions(List<IListDataExporter> exportDefinition) {
		m_ExportDefinition = exportDefinition;
	}

	public void addExportDefinition(IListDataExporter ilCurrent) {
		if (m_ExportDefinition == null) {
			m_ExportDefinition = new ArrayList<>();
		}
		m_ExportDefinition.add(ilCurrent);
	}

	public List<ICellValue> getCellValues() {
		return m_CellValues;
	}

	public void setCellValues(List<ICellValue> cellValues) {
		m_CellValues = cellValues;
	}

	public void addCellValue(ICellValue icvCurrent) {
		if (m_CellValues == null) {
			m_CellValues = new ArrayList<>();
		}
		m_CellValues.add(icvCurrent);
	}

	@Override
	public Object saveState(FacesContext context) {
		try {

			Object[] state = new Object[5];
			state[0] = super.saveState(context);
			state[1] = m_Create;
			state[2] = m_Name;
			state[3] = StateHolderUtil.saveList(context, m_ExportDefinition);
			state[4] = StateHolderUtil.saveList(context, m_CellValues);
			return state;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_Create = (Boolean) state[1];
		m_Name = (String) state[2];
		m_ExportDefinition = StateHolderUtil.restoreList(context,
				getComponent(), state[3]);
		m_CellValues = StateHolderUtil.restoreList(context, getComponent(),
				state[4]);
	}
} public class CellBookmark extends ValueBindingObjectImpl implements ICellValue {

	private Object m_Value;
	private String m_Name;

	@Override
	public Object getValue() {
		if (m_Value != null) {
			return m_Value;
		}
		ValueBinding vb = getValueBinding("value");
		if (vb != null) {
			return vb.getValue(getFacesContext());
		}
		return null;
	}

	public String getName() {
		if (m_Name != null) {
			return m_Name;
		}
		ValueBinding vb = getValueBinding("name");
		if (vb != null) {
			return (String) vb.getValue(getFacesContext());
		}
		return null;
	}

	public void setName(String name) {
		m_Name = name;
	}

	public void setValue(Object value) {
		m_Value = value;
	}

	@Override
	public Object saveState(FacesContext context) {
		Object[] state = new Object[3];
		state[0] = super.saveState(context);
		state[1] = m_Name;
		state[2] = m_Value;
		return state;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_Name = (String)state[1];
		m_Value = state[2];
	}
} public class CellValue extends ValueBindingObjectImpl implements ICellValue {

	private Object m_Value;
	private Integer m_ColumnNumber;
	private Integer m_RowNumber;
	private Boolean m_CellFormula = false;
	private PoiCellStyle m_PoiCellStyle;

	public int getRowNumber() {
		if (m_RowNumber != null) {
			return m_RowNumber;
		}
		ValueBinding vb = getValueBinding("rowNumber");
		if (vb != null) {
			Integer intValue = (Integer) vb.getValue(getFacesContext());
			if (intValue != null) {
				return intValue;
			}
		}
		return 0;

	}

	public void setRowNumber(int rowNumber) {
		m_RowNumber = rowNumber;
	}

	@Override
	public Object getValue() {
		if (m_Value != null) {
			return m_Value;
		}
		ValueBinding vb = getValueBinding("value");
		if (vb != null) {
			return vb.getValue(getFacesContext());
		}
		return null;
	}

	public void setValue(Object value) {
		m_Value = value;
	}

	public int getColumnNumber() {
		if (m_ColumnNumber != null) {
			return m_ColumnNumber;
		}
		ValueBinding vb = getValueBinding("columnNumber");
		if (vb != null) {
			Integer intValue = (Integer) vb.getValue(getFacesContext());
			if (intValue != null) {
				return intValue;
			}
		}
		return 0;
	}

	public void setColumnNumber(int columnNumber) {
		m_ColumnNumber = columnNumber;
	}


	public boolean isCellFormula() {
		return m_CellFormula;
	}

	public void setCellFormula(boolean cellFormula) {
		m_CellFormula = cellFormula;
	}

	public PoiCellStyle getPoiCellStyle() {
			return m_PoiCellStyle;
	}

	public void setPoiCellStyle(PoiCellStyle poiCellStyle) {
		m_PoiCellStyle = poiCellStyle;
	}

	public PoiCellStyle getCellStyle() {
		return getPoiCellStyle();
	}

	public void setCellStyle(PoiCellStyle poiCellStyle) {
		setPoiCellStyle(poiCellStyle);
	}
	@Override
	public Object saveState(FacesContext context) {
		Object[] state = new Object[6];
		state[0] = super.saveState(context);
		state[1] = m_ColumnNumber;
		state[2] = m_RowNumber;
		state[3] = m_Value;
		state[4] = m_CellFormula;
		state[5] = FacesUtil.objectToSerializable(context, m_PoiCellStyle);
		return state;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_ColumnNumber = (Integer)state[1];
		m_RowNumber = (Integer)state[2];
		m_Value = state[3];
		m_CellFormula = (Boolean) state[4];
		m_PoiCellStyle = (PoiCellStyle) FacesUtil.objectFromSerializable(context, state[5]);
	}
} public interface ICellValue {

	public Object getValue();
} public class PoiCellStyle extends ValueBindingObjectImpl {

	private String m_Alignment;
	private String m_BorderBottom;
	private String m_BorderTop;
	private String m_BorderRight;
	private String m_BorderLeft;
	private String m_BottomBorderColor;
	private String m_DataFormat;
	private String m_FillBackgroundColor;
	private String m_FillForegroundColor;
	private String m_FillPattern;
	private String m_FontBoldweight;
	private String m_FontColor;
	private Short m_FontHeightInPoints = 0;
	private String m_FontName;
	private Boolean m_FontItalic = false;
	private Boolean m_FontStrikeout = false;
	private String m_FontUnderline;
	private String m_FontTypeOffset;
	private Boolean m_Hidden = false;
	private String m_Indention;
	private String m_LeftBorderColor;
	private Boolean m_Locked = false;
	private String m_RightBorderColor;
	private Short m_Rotation = 0;
	private String m_TopBorderColor;
	private String m_VerticalAlignment;
	private Boolean m_WrapText = false;
	/*
	 * A initialized CellStyle object, only to make the generationProcess much
	 * faster and do NOT save it via save/restore state
	 */
	private CellStyle m_CellStyle;

	public CellStyle getCellStyle() {
		return m_CellStyle;
	}

	public void setCellStyle(CellStyle cellStyle) {
		m_CellStyle = cellStyle;
	}

	public String getAlignment() {
		return getStringValue(m_Alignment, "aligment", this, null, getFacesContext());
	}

	public void setAlignment(String alignment) {
		m_Alignment = alignment;
	}

	public String getBorderBottom() {
		return getStringValue(m_BorderBottom, "borderBottom", this, null, getFacesContext());
	}

	public void setBorderBottom(String borderBottom) {
		m_BorderBottom = borderBottom;
	}

	public String getBorderTop() {
		return getStringValue(m_BorderTop, "borderTop", this, null, getFacesContext());
	}

	public void setBorderTop(String borderTop) {
		m_BorderTop = borderTop;
	}

	public String getBorderRight() {
		return getStringValue(m_BorderRight, "borderRight", this, null, getFacesContext());
	}

	public void setBorderRight(String borderRight) {
		m_BorderRight = borderRight;
	}

	public String getBorderLeft() {
		return getStringValue(m_BorderLeft, "borderLeft", this, null, getFacesContext());
	}

	public void setBorderLeft(String borderLeft) {
		m_BorderLeft = borderLeft;
	}

	public String getBottomBorderColor() {
		return getStringValue(m_BottomBorderColor, "bottomBorderColor", this, null, getFacesContext());
	}

	public void setBottomBorderColor(String bottomBorderColor) {
		m_BottomBorderColor = bottomBorderColor;
	}

	public String getDataFormat() {
		return getStringValue(m_DataFormat, "dataFormat", this, null, getFacesContext());
	}

	public void setDataFormat(String dataFormat) {
		m_DataFormat = dataFormat;
	}

	public String getFillBackgroundColor() {
		return getStringValue(m_FillBackgroundColor, "fillBackgroundColor", this, null, getFacesContext());
	}

	public void setFillBackgroundColor(String fillBackgroundColor) {
		m_FillBackgroundColor = fillBackgroundColor;
	}

	public String getFillForegroundColor() {
		return getStringValue(m_FillForegroundColor, "fillForegroundColor", this, null, getFacesContext());
	}

	public void setFillForegroundColor(String fillForegroundColor) {
		m_FillForegroundColor = fillForegroundColor;
	}

	public String getFillPattern() {
		return getStringValue(m_FillPattern, "fillPattern", this, null, getFacesContext());
	}

	public void setFillPattern(String fillPattern) {
		m_FillPattern = fillPattern;
	}

	public String getFontBoldweight() {
		return getStringValue(m_FontBoldweight, "fontBoldweight", this, null, getFacesContext());
	}

	public void setFontBoldweight(String fontBoldweight) {
		m_FontBoldweight = fontBoldweight;
	}

	public String getFontColor() {
		return getStringValue(m_FontColor, "fontColor", this, null, getFacesContext());
	}

	public void setFontColor(String fontColor) {
		m_FontColor = fontColor;
	}

	public short getFontHeightInPoints() {
		return getShortValue(m_FontHeightInPoints, "fontHeightInPoints", this, null, getFacesContext());
	}

	public void setFontHeightInPoints(short fontHeightInPoints) {
		m_FontHeightInPoints = fontHeightInPoints;
	}

	public String getFontName() {
		return getStringValue(m_FontName, "fontName", this, null, getFacesContext());
	}

	public void setFontName(String fontName) {
		m_FontName = fontName;
	}

	public boolean isFontItalic() {
		return getBooleanValue(m_FontItalic, "fontItalic", this, null, getFacesContext());
	}

	public void setFontItalic(boolean fontItalic) {
		this.m_FontItalic = fontItalic;
	}

	public boolean isFontStrikeout() {
		return getBooleanValue(m_FontStrikeout, "fontStrikeout", this, null, getFacesContext());
	}

	public void setFontStrikeout(boolean fontStrikeout) {
		this.m_FontStrikeout = fontStrikeout;
	}

	public String getFontUnderline() {
		return getStringValue(m_FontUnderline, "fontUnderline", this, null, getFacesContext());
	}

	public void setFontUnderline(String fontUnderline) {
		this.m_FontUnderline = fontUnderline;
	}

	public String getFontTypeOffset() {
		return getStringValue(m_FontTypeOffset, "fontTypeOffset", this, null, getFacesContext());
	}

	public void setFontTypeOffset(String fontTypeOffset) {
		m_FontTypeOffset = fontTypeOffset;
	}

	public boolean isHidden() {
		return getBooleanValue(m_Hidden, "hidden", this, null, getFacesContext());
	}

	public void setHidden(boolean hidden) {
		m_Hidden = hidden;
	}

	public String getIndention() {
		return getStringValue(m_Indention, "indention", this, null, getFacesContext());
	}

	public void setIndention(String indention) {
		m_Indention = indention;
	}

	public String getLeftBorderColor() {
		return getStringValue(m_LeftBorderColor, "leftBorderColor", this, null, getFacesContext());
	}

	public void setLeftBorderColor(String leftBorderColor) {
		m_LeftBorderColor = leftBorderColor;
	}

	public boolean isLocked() {
		return getBooleanValue(m_Locked, "locked", this, null, getFacesContext());
	}

	public void setLocked(boolean locked) {
		m_Locked = locked;
	}

	public String getRightBorderColor() {
		return getStringValue(m_RightBorderColor, "rightBorderColor", this, null, getFacesContext());
	}

	public void setRightBorderColor(String rightBorderColor) {
		m_RightBorderColor = rightBorderColor;
	}

	public short getRotation() {
		return getShortValue(m_Rotation, "rotation", this, null, getFacesContext());
	}

	public void setRotation(short rotation) {
		m_Rotation = rotation;
	}

	public String getTopBorderColor() {
		return getStringValue(m_TopBorderColor, "topBorderColor", this, null, getFacesContext());
	}

	public void setTopBorderColor(String topBorderColor) {
		m_TopBorderColor = topBorderColor;
	}

	public String getVerticalAlignment() {
		return getStringValue(m_VerticalAlignment, "verticalAlignment", this, null, getFacesContext());
	}

	public void setVerticalAlignment(String verticalAlignment) {
		m_VerticalAlignment = verticalAlignment;
	}

	public boolean isWrapText() {
		return getBooleanValue(m_WrapText, "wrapText", this, null, getFacesContext());
	}

	public void setWrapText(boolean wrapText) {
		m_WrapText = wrapText;
	}

	@Override
	public Object saveState(FacesContext context) {
		Object[] state = new Object[28];
		state[0] = super.saveState(context);
		state[1] = m_Alignment;
		state[2] = m_BorderBottom;
		state[3] = m_BorderTop;
		state[4] = m_BorderRight;
		state[5] = m_BorderLeft;
		state[6] = m_BottomBorderColor;
		state[7] = m_DataFormat;
		state[8] = m_FillBackgroundColor;
		state[9] = m_FillForegroundColor;
		state[10] = m_FillPattern;
		state[11] = m_FontBoldweight;
		state[12] = m_FontColor;
		state[13] = m_FontHeightInPoints;
		state[14] = m_FontItalic;
		state[15] = m_FontName;
		state[16] = m_FontStrikeout;
		state[17] = m_FontUnderline;
		state[18] = m_FontTypeOffset;
		state[19] = m_Hidden;
		state[20] = m_Indention;
		state[21] = m_LeftBorderColor;
		state[22] = m_Locked;
		state[23] = m_RightBorderColor;
		state[24] = m_Rotation;
		state[25] = m_TopBorderColor;
		state[26] = m_VerticalAlignment;
		state[27] = m_WrapText;
		return state;
	}

	@Override
	public void restoreState(FacesContext context, Object arg1) {
		Object[] state = (Object[]) arg1;
		super.restoreState(context, state[0]);
		m_Alignment = (String) state[1];
		m_BorderBottom = (String) state[2];
		m_BorderTop = (String) state[3];
		m_BorderRight = (String) state[4];
		m_BorderLeft = (String) state[5];
		m_BottomBorderColor = (String) state[6];
		m_DataFormat = (String) state[7];
		m_FillBackgroundColor = (String) state[8];
		m_FillForegroundColor = (String) state[9];
		m_FillPattern = (String) state[10];
		m_FontBoldweight = (String) state[11];
		m_FontColor = (String) state[12];
		m_FontHeightInPoints = (Short) state[13];
		m_FontItalic = (Boolean) state[14];
		m_FontName = (String) state[15];
		m_FontStrikeout = (Boolean) state[16];
		m_FontUnderline = (String) state[17];
		m_FontTypeOffset = (String) state[18];
		m_Hidden = (Boolean) state[19];
		m_Indention = (String) state[20];
		m_LeftBorderColor = (String) state[21];
		m_Locked = (Boolean) state[22];
		m_RightBorderColor = (String) state[23];
		m_Rotation = (Short) state[24];
		m_TopBorderColor = (String) state[25];
		m_VerticalAlignment = (String) state[26];
		m_WrapText = (Boolean) state[27];
	}

} public enum MethodExecutor {
	INSTANCE;

	public void execute(MethodBinding method, UIComponent comp, FacesContext context, Object bo) throws PrivilegedActionException {
		if (method != null) {
			Object[] params = null;
			if (method instanceof MethodBindingEx) {
				params = new Object[] { bo };
				((MethodBindingEx) method).setComponent(comp);
				((MethodBindingEx) method).setParamNames(new String[] { "result" });
			}

			executePrivileged(method, context, params);
		}
	}

	private void executePrivileged(final MethodBinding method, final FacesContext context, final Object[] params) throws PrivilegedActionException {
		AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
			method.invoke(context, params);
			return null;
		});
	}
} public class EmbeddedDataSourceExportProcessor implements IDataSourceExportProcessor {

	private static EmbeddedDataSourceExportProcessor m_Processor;

	private EmbeddedDataSourceExportProcessor() {
	}

	public static EmbeddedDataSourceExportProcessor getInstance() {
		if (m_Processor == null) {
			m_Processor = new EmbeddedDataSourceExportProcessor();
		}
		return m_Processor;
	}

	@Override
	public void processExportRow(Data2RowExporter lstExport, Sheet shProcess, FacesContext context, String strVar, String strIndex) throws POIException {

		Logger logCurrent = LoggerFactory.getLogger(this.getClass().getCanonicalName());

		try {
			logCurrent.finer("Proccess Export Row");
			IExportSource is = lstExport.getDataSource();

			logCurrent.finer("Load Access Source");
			int nAccess = is.accessSource();
			if (nAccess < 1) {
				throw new POIException("Error accessing Source: " + is.getClass() + " Error: " + nAccess);
			}
			int nRow = lstExport.getStartRow();
			int nStepSize = lstExport.getStepSize();

			int nCount = 0;

			logCurrent.finer("Start Processing Cells");
			List<ShadowedObject> controlData = RequestVarsHandler.INSTANCE.publishControlData(context, strVar, strIndex);
			while (is.accessNextRow() == 1) {
				nCount++;
				RequestVarsHandler.INSTANCE.pushVars(context, strVar, strIndex, is.getDataRow(), nCount);
				for (ColumnDefinition clDef : lstExport.getColumns()) {
					int nCol = clDef.getColumnNumber();
					int nMyRow = clDef.getRowShift() + nRow;
					Object objCurrent = is.getValue(clDef, context);
					WorkbookProcessor.INSTANCE.setCellValue(shProcess, nMyRow, nCol, objCurrent, clDef.isCellFormula(), clDef.getPoiCellStyle());
				}
				RequestVarsHandler.INSTANCE.removeVars(context, strVar, strIndex);
				nRow = nRow + nStepSize;
			}
			RequestVarsHandler.INSTANCE.revokeControlData(controlData, context);
			is.closeSource();
			logCurrent.finer("Proccess Export Row - DONE");
		} catch (Exception e) {
			throw new POIException("Error in processExportRow", e);
		}
	}

	@Override
	public void processExportCol(Data2ColumnExporter lstExport, Sheet shProcess, FacesContext context, String strVar, String strIndex) throws POIException {
		IExportSource is = lstExport.getDataSource();
		int nAccess = is.accessSource();
		if (nAccess < 1) {
			throw new POIException("Error accessing Source: " + is.getClass() + " Error: " + nAccess);
		}
		try {
			int nCol = lstExport.getStartColumn();
			int nStepSize = lstExport.getStepSize();
			int nCount = 0;
			List<ShadowedObject> controlData = RequestVarsHandler.INSTANCE.publishControlData(context, strVar, strIndex);
			while (is.accessNextRow() == 1) {
				nCount++;
				RequestVarsHandler.INSTANCE.pushVars(context, strVar, strIndex, is.getDataRow(), nCount);
				for (RowDefinition rdDef : lstExport.getRows()) {
					int nMyCol = rdDef.getColumnShift() + nCol;
					int nRow = rdDef.getRowNumber();
					Object objCurrent = is.getValue(rdDef, context);
					WorkbookProcessor.INSTANCE.setCellValue(shProcess, nRow, nMyCol, objCurrent, rdDef.isCellFormula(), rdDef.getPoiCellStyle());
				}
				RequestVarsHandler.INSTANCE.removeVars(context, strVar, strIndex);
				nCol = nCol + nStepSize;
			}
			RequestVarsHandler.INSTANCE.revokeControlData(controlData, context);
			is.closeSource();
		} catch (Exception e) {
			throw new POIException("Error in processExportCol", e);
		}
	}

} public enum POICellStyleProcessor {
	INSTANCE;

	private Map<String, Short> m_StyleConstantValues;
	private Map<String, HorizontalAlignment> m_alignmentValues;
	private Map<String, BorderStyle> m_borderValues;
	private Map<String, FillPatternType> m_fillPatternValues;
	private Map<String, VerticalAlignment> m_vertAlignmentValues;
	private Map<String, Byte> m_StyleByteConstantValues;

	public CellStyle buildStyle(Sheet sheet, PoiCellStyle pCellStyle) {
		checkStyleConstantValues();
		CellStyle style = sheet.getWorkbook().createCellStyle();

		// Create a new font and alter it.
		Font font = sheet.getWorkbook().createFont();

		if (pCellStyle.getAlignment() != null)
			style.setAlignment(m_alignmentValues.get(pCellStyle.getAlignment()));

		if (pCellStyle.getBorderBottom() != null)
			style.setBorderBottom(m_borderValues.get(pCellStyle.getBorderBottom()));

		if (pCellStyle.getBorderLeft() != null)
			style.setBorderLeft(m_borderValues.get(pCellStyle.getBorderLeft()));

		if (pCellStyle.getBorderRight() != null)
			style.setBorderRight(m_borderValues.get(pCellStyle.getBorderRight()));

		if (pCellStyle.getBorderTop() != null)
			style.setBorderTop(m_borderValues.get(pCellStyle.getBorderTop()));

		if (pCellStyle.getDataFormat() != null) {
			DataFormat format = sheet.getWorkbook().createDataFormat();
			style.setDataFormat(format.getFormat(pCellStyle.getDataFormat()));
		}

		if (pCellStyle.getFillPattern() != null)
			style.setFillPattern(m_fillPatternValues.get(pCellStyle.getFillPattern()));

		if (pCellStyle.getFontBoldweight() != null)
			if("BOLDWEIGHT_BOLD".equals(pCellStyle.getFontBoldweight())) { //$NON-NLS-1$
				font.setBold(true);
			} else {
				font.setBold(false);
			}

		if (pCellStyle.getFontHeightInPoints() != 0)
			font.setFontHeightInPoints(pCellStyle.getFontHeightInPoints());

		if (pCellStyle.getFontName() != null)
			font.setFontName(pCellStyle.getFontName());

		if (pCellStyle.isFontItalic())
			font.setItalic(pCellStyle.isFontItalic());

		if (pCellStyle.isFontStrikeout())
			font.setStrikeout(pCellStyle.isFontStrikeout());

		if (pCellStyle.getFontUnderline() != null)
			font.setUnderline(m_StyleByteConstantValues.get(pCellStyle.getFontUnderline()));

		if (pCellStyle.getFontTypeOffset() != null)
			font.setTypeOffset(m_StyleConstantValues.get(pCellStyle.getFontTypeOffset()));

		// Set Font
		style.setFont(font);

		if (pCellStyle.isHidden())
			style.setHidden(pCellStyle.isHidden());

		if (pCellStyle.getIndention() != null)
			style.setIndention(m_StyleConstantValues.get(pCellStyle.getIndention()));

		if (pCellStyle.isLocked())
			style.setLocked(pCellStyle.isLocked());

		if (pCellStyle.getRotation() != 0)
			style.setRotation(pCellStyle.getRotation());

		if (pCellStyle.getVerticalAlignment() != null)
			style.setVerticalAlignment(m_vertAlignmentValues.get(pCellStyle.getVerticalAlignment()));

		if (pCellStyle.isWrapText())
			style.setWrapText(pCellStyle.isWrapText());

		if (sheet.getWorkbook() instanceof XSSFWorkbook || sheet.getWorkbook() instanceof SXSSFWorkbook) {
			processXSSColor((XSSFCellStyle) style, sheet, pCellStyle, font);
		} else {
			processHSFFColor(style, sheet, pCellStyle, font);
		}
		return style;
	}

	private void processHSFFColor(CellStyle style, Sheet sheet, PoiCellStyle pCellStyle, Font font) {
		if (pCellStyle.getBottomBorderColor() != null)
			style.setBottomBorderColor(getHSFFColor(pCellStyle.getBottomBorderColor(), sheet));

		if (pCellStyle.getFillBackgroundColor() != null)
			style.setFillBackgroundColor(getHSFFColor(pCellStyle.getFillBackgroundColor(), sheet));

		if (pCellStyle.getFillForegroundColor() != null)
			style.setFillForegroundColor(getHSFFColor(pCellStyle.getFillForegroundColor(), sheet));

		if (pCellStyle.getFontColor() != null)
			font.setColor(getHSFFColor(pCellStyle.getFontColor(), sheet));

		if (pCellStyle.getTopBorderColor() != null)
			style.setTopBorderColor(getHSFFColor(pCellStyle.getTopBorderColor(), sheet));

		if (pCellStyle.getRightBorderColor() != null)
			style.setRightBorderColor(getHSFFColor(pCellStyle.getRightBorderColor(), sheet));

		if (pCellStyle.getLeftBorderColor() != null)
			style.setLeftBorderColor(getHSFFColor(pCellStyle.getLeftBorderColor(), sheet));

	}

	private short getHSFFColor(String color, Sheet sheet) {
		if (isIndexColor(color)) {
			return IndexedColors.valueOf(color).getIndex();
		}
		HSSFPalette palette = ((HSSFWorkbook) sheet.getWorkbook()).getCustomPalette();
		Color clr = Color.decode(color);
		HSSFColor myColor = palette.findSimilarColor(clr.getRed(), clr.getGreen(), clr.getBlue());
		if (myColor == null) {
			myColor = palette.addColor((byte) clr.getRed(), (byte) clr.getGreen(), (byte) clr.getBlue());
		}
		return myColor.getIndex();
	}

	private boolean isIndexColor(String colorName) {
		for (IndexedColors color : IndexedColors.values()) {
			if (color.name().equals(colorName)) {
				return true;
			}
		}
		return false;
	}

	private void processXSSColor(XSSFCellStyle style, Sheet sheet, PoiCellStyle pCellStyle, Font font) {

		if (pCellStyle.getBottomBorderColor() != null) {
			String color = pCellStyle.getBottomBorderColor();
			if (isIndexColor(color)) {
				style.setBottomBorderColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setBottomBorderColor(getXSSFColor(color));
			}
		}
		if (pCellStyle.getFillBackgroundColor() != null) {
			String color = pCellStyle.getFillBackgroundColor();
			if (isIndexColor(color)) {
				style.setFillBackgroundColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setFillBackgroundColor(getXSSFColor(color));
			}
		}

		if (pCellStyle.getFillForegroundColor() != null) {
			String color = pCellStyle.getFillForegroundColor();
			if (isIndexColor(color)) {
				style.setFillForegroundColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setFillForegroundColor(getXSSFColor(color));
			}
		}

		if (pCellStyle.getFontColor() != null) {
			String color = pCellStyle.getFontColor();
			if (isIndexColor(color)) {
				font.setColor(IndexedColors.valueOf(color).getIndex());
			} else {
				((XSSFFont) font).setColor(getXSSFColor(color));
			}
		}

		if (pCellStyle.getTopBorderColor() != null) {
			String color = pCellStyle.getTopBorderColor();
			if (isIndexColor(color)) {
				style.setTopBorderColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setTopBorderColor(getXSSFColor(color));
			}
		}

		if (pCellStyle.getRightBorderColor() != null) {
			String color = pCellStyle.getRightBorderColor();
			if (isIndexColor(color)) {
				style.setRightBorderColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setRightBorderColor(getXSSFColor(color));
			}
		}

		if (pCellStyle.getLeftBorderColor() != null) {
			String color = pCellStyle.getLeftBorderColor();
			if (isIndexColor(color)) {
				style.setLeftBorderColor(IndexedColors.valueOf(color).getIndex());
			} else {
				style.setLeftBorderColor(getXSSFColor(color));
			}
		}

	}

	private XSSFColor getXSSFColor(String color) {
		Color clr = Color.decode(color);
		XSSFColor myColor = new XSSFColor(clr, new DefaultIndexedColorMap());
		return myColor;
	}

	private synchronized void checkStyleConstantValues() {
		if(m_alignmentValues == null) {
			this.m_alignmentValues = new HashMap<>();
			m_alignmentValues.put("ALIGN_CENTER", HorizontalAlignment.CENTER); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_CENTER_SELECTION", HorizontalAlignment.CENTER_SELECTION); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_FILL", HorizontalAlignment.FILL); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_GENERAL", HorizontalAlignment.GENERAL); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_JUSTIFY", HorizontalAlignment.JUSTIFY); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_LEFT", HorizontalAlignment.LEFT); //$NON-NLS-1$
			m_alignmentValues.put("ALIGN_RIGHT", HorizontalAlignment.RIGHT); //$NON-NLS-1$
		}
		if(m_borderValues == null) {
			this.m_borderValues = new HashMap<>();

			m_borderValues.put("BORDER_DASH_DOT", BorderStyle.DASH_DOT); //$NON-NLS-1$
			m_borderValues.put("BORDER_DASH_DOT_DOT", BorderStyle.DASH_DOT_DOT); //$NON-NLS-1$
			m_borderValues.put("BORDER_DASHED", BorderStyle.DASHED); //$NON-NLS-1$
			m_borderValues.put("BORDER_DOTTED", BorderStyle.DOTTED); //$NON-NLS-1$
			m_borderValues.put("BORDER_DOUBLE", BorderStyle.DOUBLE); //$NON-NLS-1$
			m_borderValues.put("BORDER_HAIR", BorderStyle.HAIR); //$NON-NLS-1$
			m_borderValues.put("BORDER_MEDIUM", BorderStyle.MEDIUM); //$NON-NLS-1$
			m_borderValues.put("BORDER_MEDIUM_DASH_DOT", BorderStyle.MEDIUM_DASH_DOT); //$NON-NLS-1$
			m_borderValues.put("BORDER_MEDIUM_DASH_DOT_DOT", BorderStyle.MEDIUM_DASH_DOT_DOT); //$NON-NLS-1$
			m_borderValues.put("BORDER_MEDIUM_DASHED", BorderStyle.MEDIUM_DASHED); //$NON-NLS-1$
			m_borderValues.put("BORDER_NONE", BorderStyle.NONE); //$NON-NLS-1$
			m_borderValues.put("BORDER_SLANTED_DASH_DOT", BorderStyle.SLANTED_DASH_DOT); //$NON-NLS-1$
			m_borderValues.put("BORDER_THICK", BorderStyle.THICK); //$NON-NLS-1$
			m_borderValues.put("BORDER_THIN", BorderStyle.THIN); //$NON-NLS-1$
		}
		if(m_fillPatternValues == null) {
			this.m_fillPatternValues = new HashMap<>();
			m_fillPatternValues.put("ALT_BARS", FillPatternType.ALT_BARS); //$NON-NLS-1$
			m_fillPatternValues.put("BIG_SPOTS", FillPatternType.BIG_SPOTS); //$NON-NLS-1$
			m_fillPatternValues.put("BRICKS", FillPatternType.BRICKS); //$NON-NLS-1$
			m_fillPatternValues.put("DIAMONDS", FillPatternType.DIAMONDS); //$NON-NLS-1$
			m_fillPatternValues.put("FINE_DOTS", FillPatternType.FINE_DOTS); //$NON-NLS-1$
			m_fillPatternValues.put("LEAST_DOTS", FillPatternType.LEAST_DOTS); //$NON-NLS-1$
			m_fillPatternValues.put("LESS_DOTS", FillPatternType.LESS_DOTS); //$NON-NLS-1$
			m_fillPatternValues.put("NO_FILL", FillPatternType.NO_FILL); //$NON-NLS-1$
			m_fillPatternValues.put("SOLID_FOREGROUND", FillPatternType.SOLID_FOREGROUND); //$NON-NLS-1$
			m_fillPatternValues.put("SPARSE_DOTS", FillPatternType.SPARSE_DOTS); //$NON-NLS-1$
			m_fillPatternValues.put("SQUARES", FillPatternType.SQUARES); //$NON-NLS-1$

			m_fillPatternValues.put("THICK_BACKWARD_DIAG", FillPatternType.THICK_BACKWARD_DIAG); //$NON-NLS-1$
			m_fillPatternValues.put("THICK_FORWARD_DIAG", FillPatternType.THICK_FORWARD_DIAG); //$NON-NLS-1$
			m_fillPatternValues.put("THICK_HORZ_BANDS", FillPatternType.THICK_HORZ_BANDS); //$NON-NLS-1$
			m_fillPatternValues.put("THICK_VERT_BANDS", FillPatternType.THICK_VERT_BANDS); //$NON-NLS-1$
			m_fillPatternValues.put("THIN_BACKWARD_DIAG", FillPatternType.THIN_BACKWARD_DIAG); //$NON-NLS-1$
			m_fillPatternValues.put("THIN_FORWARD_DIAG", FillPatternType.THIN_FORWARD_DIAG); //$NON-NLS-1$
			m_fillPatternValues.put("THIN_HORZ_BANDS", FillPatternType.THIN_HORZ_BANDS); //$NON-NLS-1$
			m_fillPatternValues.put("THIN_VERT_BANDS", FillPatternType.THIN_VERT_BANDS); //$NON-NLS-1$
		}
		if(m_vertAlignmentValues == null) {
			m_vertAlignmentValues = new HashMap<>();

			m_vertAlignmentValues.put("VERTICAL_BOTTOM", VerticalAlignment.BOTTOM); //$NON-NLS-1$
			m_vertAlignmentValues.put("VERTICAL_CENTER", VerticalAlignment.CENTER); //$NON-NLS-1$
			m_vertAlignmentValues.put("VERTICAL_JUSTIFY", VerticalAlignment.JUSTIFY); //$NON-NLS-1$
			m_vertAlignmentValues.put("VERTICAL_TOP", VerticalAlignment.TOP); //$NON-NLS-1$
		}
		if (m_StyleConstantValues == null) {
			m_StyleConstantValues = new HashMap<>();

			m_StyleConstantValues.put("SS_NONE", Font.SS_NONE); //$NON-NLS-1$
			m_StyleConstantValues.put("SS_SUPER", Font.SS_SUPER); //$NON-NLS-1$
			m_StyleConstantValues.put("SS_SUB", Font.SS_SUB); //$NON-NLS-1$

		}

		if (m_StyleByteConstantValues == null) {
			m_StyleByteConstantValues = new HashMap<>();
			m_StyleByteConstantValues.put("U_NONE", Font.U_NONE); //$NON-NLS-1$
			m_StyleByteConstantValues.put("U_SINGLE", Font.U_SINGLE); //$NON-NLS-1$
			m_StyleByteConstantValues.put("U_DOUBLE", Font.U_DOUBLE); //$NON-NLS-1$
			m_StyleByteConstantValues.put("U_SINGLE_ACCOUNTING", Font.U_SINGLE_ACCOUNTING); //$NON-NLS-1$
			m_StyleByteConstantValues.put("U_DOUBLE_ACCOUNTING", Font.U_DOUBLE_ACCOUNTING); //$NON-NLS-1$
		}
	}

} public class XPagesDataSourceExportProcessor implements IDataSourceExportProcessor {

	private static XPagesDataSourceExportProcessor m_Processor;

	private XPagesDataSourceExportProcessor() {

	}

	public static XPagesDataSourceExportProcessor getInstances() {
		if (m_Processor == null) {
			m_Processor = new XPagesDataSourceExportProcessor();
		}
		return m_Processor;
	}

	@Override
	public void processExportRow(Data2RowExporter lstExport, Sheet shProcess, FacesContext context, String strVar, String strIndex) throws POIException {

		DataSource ds = lstExport.getPageDataSource();

		if (ds != null) {
			try {
				TabularDataModel tdm = getTDM(ds, context);
				int nRow = lstExport.getStartRow();
				int nStepSize = lstExport.getStepSize();
				int nDSRCount = tdm.getRowCount();
				List<ShadowedObject> controlData = RequestVarsHandler.INSTANCE.publishControlData(context, strVar, strIndex);
				for (int nCount = 0; nCount < nDSRCount; nCount++) {
					tdm.setRowIndex(nCount);
					if (tdm.isRowAvailable()) {
						RequestVarsHandler.INSTANCE.pushVars(context, strVar, strIndex, tdm.getRowData(), nCount);
						for (ColumnDefinition clDef : lstExport.getColumns()) {
							int nCol = clDef.getColumnNumber();
							int nMyRow = clDef.getRowShift() + nRow;
							String strTitle = clDef.getColumnTitle();
							Object objCurrent = null;
							if (strTitle != null && !"".equals(strTitle)) {
								objCurrent = getColumnValue(clDef.getColumnTitle(), tdm, context);
							} else {
								objCurrent = clDef.executeComputeValue(context);
							}
							WorkbookProcessor.INSTANCE.setCellValue(shProcess, nMyRow, nCol, objCurrent, clDef.isCellFormula(), clDef.getPoiCellStyle());
						}
						RequestVarsHandler.INSTANCE.removeVars(context, strVar, strIndex);
						nRow = nRow + nStepSize;
					} else {
						System.out.println("no Row available at " + nCount);
					}
				}
				RequestVarsHandler.INSTANCE.revokeControlData(controlData, context);

			} catch (Exception e) {
				throw new POIException("Error in processExportRow", e);
			}
		} else {
			throw new POIException("No DataSource found", null);
		}
	}

	@Override
	public void processExportCol(Data2ColumnExporter lstExport, Sheet shProcess, FacesContext context, String strVar, String strIndex) throws POIException {
		DataSource ds = lstExport.getPageDataSource();

		if (ds != null) {
			try {
				TabularDataModel tdm = getTDM(ds, context);
				int nCol = lstExport.getStartColumn();
				int nStepSize = lstExport.getStepSize();
				int nDSMRRowCount = tdm.getRowCount();
				List<ShadowedObject> controlData = RequestVarsHandler.INSTANCE.publishControlData(context, strVar, strIndex);
				for (int nCount = 0; nCount < nDSMRRowCount; nCount++) {
					tdm.setRowIndex(nCount);
					if (tdm.isRowAvailable()) {
						RequestVarsHandler.INSTANCE.pushVars(context, strVar, strIndex, tdm.getRowData(), nCount);
						for (RowDefinition rdDef : lstExport.getRows()) {
							int nMyCol = rdDef.getColumnShift() + nCol;
							int nRow = rdDef.getRowNumber();
							String strTitle = rdDef.getColumnTitle();
							Object objCurrent = null;
							if (strTitle != null && !"".equals(strTitle)) {
								objCurrent = getColumnValue(rdDef.getColumnTitle(), tdm, context);
							} else {
								objCurrent = rdDef.executeComputeValue(context);
							}
							WorkbookProcessor.INSTANCE.setCellValue(shProcess, nRow, nMyCol, objCurrent, rdDef.isCellFormula(), rdDef.getPoiCellStyle());
						}
						RequestVarsHandler.INSTANCE.removeVars(context, strVar, strIndex);
						nCol = nCol + nStepSize;
					}
				}
				RequestVarsHandler.INSTANCE.revokeControlData(controlData, context);
			} catch (Exception e) {
				throw new POIException("Error in processExportCol", e);
			}
		} else {
			throw new POIException("No DataSource found", null);
		}
	}

	private TabularDataModel getTDM(DataSource dsCurrent, FacesContext context) {
		try {
			if (dsCurrent instanceof ModelDataSource) {
				ModelDataSource mds = (ModelDataSource) dsCurrent;
				AbstractDataSource ads = (AbstractDataSource) mds;
				ads.load(context);
				if (ads.getBeanId() == null) {

				}
				DataModel tdm = mds.getDataModel();
				if (tdm instanceof DominoViewDataModel) {
					DominoViewDataModel tdmv = (DominoViewDataModel) tdm;
					// tdmv.setDataControl(new DummyDataIterator());
					UIDataEx uidEX = new UIDataEx();
					tdmv.setDataControl(uidEX);
					tdmv.getRowCount();
					ViewNavigatorEx nav = tdmv.getDominoViewDataContainer().getNavigator();
					if (nav instanceof NOIViewNavigatorEx9) {
						((com.ibm.xsp.model.domino.viewnavigator.NOIViewNavigatorEx9) nav).calculateExactCount(tdmv.getView());
					} else {
						((com.ibm.xsp.model.domino.viewnavigator.NOIViewNavigatorEx) nav).calculateExactCount(tdmv.getView());
					}
					uidEX.setRows(tdmv.getRowCount());
					return tdmv;
				}
				if (tdm instanceof TabularDataModel) {
					TabularDataModel tds = (TabularDataModel) tdm;
					return tds;
				}
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	private Object getColumnValue(String strColName, TabularDataModel tdm, FacesContext context) {
		if (StringUtil.isNotEmpty(strColName)) {
			// Read from a rowData object
			Object rowData = tdm.getRowData();
			if (rowData instanceof ViewRowData) {
				ViewRowData vr = (ViewRowData) rowData;
				return vr.getColumnValue(strColName);
			}
			// Use the JSF property resolver
			PropertyResolver pr = context.getApplication().getPropertyResolver();
			return pr.getValue(rowData, strColName);
		}

		// Ok no value found
		return null;

	}

} public class POIException extends Exception {


	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	public POIException() {
		super();
	}
	public POIException(String strMessage) {
		super(strMessage);
	}
	public POIException(Throwable t) {
		super(t);
	}
	public POIException(String strMessage,Throwable t) {
		super(strMessage,t);
	}
} public class ErrorPageBuilder {

	private static ErrorPageBuilder m_Builder;

	private ErrorPageBuilder() {

	}

	public static ErrorPageBuilder getInstance() {
		if (m_Builder == null) {
			m_Builder = new ErrorPageBuilder();
		}
		return m_Builder;
	}

	public void processError(HttpServletResponse httpResponse,
			String strErrorMessage, Throwable t) {
		try {
			httpResponse.setContentType("text/plain");
			PrintWriter pw = httpResponse.getWriter();
			pw.println("POI 4 XPages -> ERROR");
			pw.println("--------------------------------------------------------------");
			pw.println("Error    : " + strErrorMessage);
			pw.println("POI LIB  : " + LibUtil.getPOILibUtilVersion());
			if (t != null) {
				pw.println("StackTrace:");
				t.printStackTrace(pw);
			}
			pw.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
} public class LoggerFactory {
	private static HashMap<String, Logger> m_RegistredLoggers = new HashMap<>();

	private static int m_logLevel = -1;
	private static int m_logLevelPDF = -1;
	private static int m_logLevelFOP = -1;

	public static Logger getLogger(String strName) {
		try {
			if (m_RegistredLoggers.containsKey(strName)) {
				return m_RegistredLoggers.get(strName);
			}
			Logger logRC = java.util.logging.Logger.getAnonymousLogger();
			if (m_logLevel == -1) {
				checkLogLevel();
			}
			logRC.setLevel(getLogLevel(getLogLevelForClass(strName)));
			ConsoleHandler ch = new ConsoleHandler(strName,
					getLogLevel(m_logLevel));
			logRC.addHandler(ch);
			m_RegistredLoggers.put(strName, logRC);
			return logRC;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Level getLogLevel(int nLevel) {
		switch (nLevel) {
		case 0:
			return Level.OFF;
		case 1:
			return Level.SEVERE;
		case 2:
			return Level.WARNING;
		case 3:
			return Level.INFO;
		case 4:
			return Level.FINE;
		case 5:
			return Level.FINER;
		case 6:
			return Level.FINEST;

		}
		return Level.ALL;

	}

	private static void checkLogLevel() {
		try {
			String strPOI = LibUtil.getCurrentSession().getEnvironmentString(
					"DEBUG_POI", true);
			if (strPOI == null || "".equals(strPOI)) {
				m_logLevel = 1;
			}
			String strPOIPDF = LibUtil.getCurrentSession()
					.getEnvironmentString("DEBUG_POI_PDF", true);
			if (strPOIPDF == null || "".equals(strPOIPDF)) {
				m_logLevelPDF = 1;
			}
			String strPOIFOP = LibUtil.getCurrentSession()
					.getEnvironmentString("DEBUG_POI_FOP", true);
			if (strPOIFOP == null || "".equals(strPOIFOP)) {
				m_logLevelFOP = 1;
			}

			try {
				if (strPOI != null && !"".equals(strPOI)) {
					m_logLevel = Integer.parseInt(strPOI);
				}
				if (strPOIPDF != null && !"".equals(strPOIPDF)) {
					m_logLevelPDF = Integer.parseInt(strPOIPDF);
				}
				if (strPOIFOP != null && !"".equals(strPOIFOP)) {
					m_logLevelFOP = Integer.parseInt(strPOIFOP);
				}
			} catch (Exception e) {
				m_logLevel = 0;
			}
			System.out.println("POI     LOG-LEVEL is set to: " + strPOI +" / "+ m_logLevel);
			System.out.println("POI PDF LOG-LEVEL is set to: " + strPOIPDF+" / "+ m_logLevelPDF);
			System.out.println("POI FOP LOG-LEVEL is set to: " + strPOIFOP+" / "+ m_logLevelFOP);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static int getLogLevelForClass(String strClass) {
		if (strClass == null) {
			return m_logLevel;
		}
		if (strClass.toLowerCase().startsWith(
				"biz.webgate.dominoext.poi.pdf.fopdocx4j")) {
			return m_logLevelFOP;
		}
		if (strClass.toLowerCase().startsWith("biz.webgate.dominoext.poi.pdf")) {
			return m_logLevelPDF;
		}
		return m_logLevel;
	}
}
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.webapp.XspHttpServletResponse;
import biz.webgate.dominoext.poi.component.containers.UIWorkbook;
import biz.webgate.dominoext.poi.component.data.ITemplateSource;
import biz.webgate.dominoext.poi.component.data.ss.Data2ColumnExporter;
import biz.webgate.dominoext.poi.component.data.ss.Data2RowExporter;
import biz.webgate.dominoext.poi.component.data.ss.IListDataExporter;
import biz.webgate.dominoext.poi.component.data.ss.Spreadsheet;
import biz.webgate.dominoext.poi.component.data.ss.cell.CellBookmark;
import biz.webgate.dominoext.poi.component.data.ss.cell.CellValue;
import biz.webgate.dominoext.poi.component.data.ss.cell.ICellValue;
import biz.webgate.dominoext.poi.component.data.ss.cell.PoiCellStyle;
import biz.webgate.dominoext.poi.component.kernel.util.MethodExecutor;
import biz.webgate.dominoext.poi.component.kernel.workbook.EmbeddedDataSourceExportProcessor;
import biz.webgate.dominoext.poi.component.kernel.workbook.POICellStyleProcessor;
import biz.webgate.dominoext.poi.component.kernel.workbook.XPagesDataSourceExportProcessor;
import biz.webgate.dominoext.poi.utils.exceptions.POIException;
import biz.webgate.dominoext.poi.utils.logging.ErrorPageBuilder;
import biz.webgate.dominoext.poi.utils.logging.LoggerFactory;
/**
 * Copyright (c) 2012-2021 WebGate Consulting AG and others
 *
 * Licensed 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 biz.webgate.dominoext.poi.component.kernel;






public enum WorkbookProcessor {
	INSTANCE;

	public static WorkbookProcessor getInstance() {
		return WorkbookProcessor.INSTANCE;
	}

	public void generateNewFile(ITemplateSource itsCurrent, HttpServletResponse httpResponse, FacesContext context, UIWorkbook uiWB, boolean noDownload, MethodBinding preDownload) {
		Logger logCurrent = LoggerFactory.getLogger(this.getClass().getCanonicalName());
		List<Spreadsheet> lstSP = uiWB.getSpreadsheets();
		String strFileName = uiWB.getDownloadFileName();
		try {
			logCurrent.finer("First getting the File");
			// First getting the File
			int nTemplateAccess = itsCurrent.accessTemplate();
			if (nTemplateAccess == 1) {
				Workbook wbCurrent = processWorkbook(itsCurrent, lstSP, context, uiWB);
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				wbCurrent.write(bos);

				MethodExecutor.INSTANCE.execute(preDownload, uiWB, context, bos);
				if (!noDownload) {
					logCurrent.finer("Push the Result to the HttpServlet");
					// Push the Result to the HttpServlet
					if (strFileName.toLowerCase().endsWith(".xlsx")) {
						httpResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
					} else if (strFileName.toLowerCase().endsWith("xls")) {
						httpResponse.setContentType("application/vnd.ms-excel");

					} else {
						httpResponse.setContentType("application/octet-stream");
					}
					httpResponse.addHeader("Content-disposition", "inline; filename=\"" + strFileName + "\"");
					OutputStream os = httpResponse.getOutputStream();
					bos.writeTo(os);
					os.close();
				} else {
					OutputStream os = httpResponse.getOutputStream();
					os.close();
				}
				wbCurrent.close();
			} else {
				ErrorPageBuilder.getInstance().processError(httpResponse, "TemplateAccess Problem NR: " + nTemplateAccess, null);
			}
		} catch (Exception e) {
			ErrorPageBuilder.getInstance().processError(httpResponse, "Error during Workbookgeneration", e);
		}

	}

	public Workbook processWorkbook(ITemplateSource itsCurrent, List<Spreadsheet> lstSP, FacesContext context, UIWorkbook uiWB) throws IOException, InvalidFormatException, POIException {
		Logger logCurrent = LoggerFactory.getLogger(this.getClass().getCanonicalName());

		InputStream is = itsCurrent.getFileStream();
		// Workbook wbCurrent = WorkbookFactory.create(is);
		// ;
		Workbook wbCurrent1 = WorkbookFactory.create(is);
		Workbook wbCurrent = wbCurrent1;
		is.close();
		if (wbCurrent1 instanceof XSSFWorkbook && uiWB.isUseStreamingModel()) {
			logCurrent.info("Generation SXSSFWorkbook");
			wbCurrent = new SXSSFWorkbook((XSSFWorkbook) wbCurrent1);
		}
		itsCurrent.cleanUP();
		// Processing all Spreadsheets to the File
		logCurrent.finer("Push the Result to the HttpServlet");

		for (Spreadsheet spCurrent : lstSP) {
			processSpreadSheet(spCurrent, wbCurrent, context);
		}
		if (uiWB != null) {
			logCurrent.finer("Post Generation Process");
			uiWB.postGenerationProcess(context, wbCurrent);
		}
		return wbCurrent;
	}

	private void processSpreadSheet(Spreadsheet spCurrent, Workbook wbCurrent, FacesContext context) throws POIException {
		// Checking for Replacement Values
		Logger logCurrent = LoggerFactory.getLogger(this.getClass().getCanonicalName());

		logCurrent.finer("Proccess Spread Sheet");
		String strName = spCurrent.getName();
		Sheet shProcess = wbCurrent.getSheet(strName);
		if (shProcess == null && !spCurrent.isCreate()) {
			return;
		}
		if (shProcess == null) {
			shProcess = wbCurrent.createSheet(strName);
		}

		logCurrent.finer("Proccess Cell Values");
		if (spCurrent.getCellValues() != null) {
			for (ICellValue iCV : spCurrent.getCellValues()) {