/* * � Copyright IBM Corp. 2010 * * 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 com.ibm.xsp.extlib.component.listview; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.el.ValueBinding; import lotus.domino.NotesException; import lotus.domino.View; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.extlib.builder.ControlBuilder; import com.ibm.xsp.extlib.builder.ControlBuilder.ControlImpl; import com.ibm.xsp.extlib.builder.ControlBuilder.IControl; import com.ibm.xsp.extlib.component.domino.UIViewComponent; import com.ibm.xsp.extlib.component.dynamicview.ViewDesign; import com.ibm.xsp.extlib.component.dynamicview.ViewDesign.ColumnDef; import com.ibm.xsp.extlib.component.dynamicview.ViewDesign.ViewDef; import com.ibm.xsp.extlib.component.dynamicview.ViewDesign.ViewFactory; import com.ibm.xsp.extlib.component.rest.DominoViewService; import com.ibm.xsp.extlib.component.rest.IRestService; import com.ibm.xsp.extlib.component.rest.UIRestService; import com.ibm.xsp.util.FacesUtil; import com.ibm.xsp.util.ManagedBeanUtil; import com.ibm.xsp.util.TypedUtil; /** * @author akosugi * * ui component handler for notes list view control */ public class UIListView extends UIViewComponent { public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.listview.ListView"; // $NON-NLS-1$ public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.listview.ListView"; // $NON-NLS-1$ public static final String RENDERER_TYPE = "com.ibm.xsp.extlib.listview.ListView"; //$NON-NLS-1$ // PHIL: // Customization bean public static abstract class Customizer { public ViewFactory getViewFactory() { return null; } public boolean createColumns(FacesContext context, UIListView panel, ViewFactory f) { return false; } public IControl createColumn(FacesContext context, UIListView panel, int index, ColumnDef colDef) { return null; } public void afterCreateColumn(FacesContext context, int index, ColumnDef colDef, IControl column) { } public void afterCreateColumns(FacesContext context, UIListView panel) { } } private String structureComponentId; // dojoEvents is unused, and not serialized. // private ArrayList<DojoEvent> dojoEvents; private String onSortChanged; private Boolean hideColumns; // MWD breaking change 10/05/11 - this prop hides ALL child columns private Boolean alternateRows; private Boolean canBeNarrowMode; private Boolean showColumnNameForEmptyTitle; // formerly 'showColumnName4EmptyTitle' => breaking change on 10/03/11 private String onCellClick; private String onCellDblClick; private Boolean dynamicView; private String currentView; private String customizerBean; public UIListView() { setRendererType(RENDERER_TYPE); // dojoEvents = new ArrayList<DojoEvent>(); } @Override public String getFamily() { return COMPONENT_FAMILY; } public String getCustomizerBean() { if (customizerBean == null) { ValueBinding vb = getValueBinding("customizerBean"); //$NON-NLS-1$ if (vb != null) { return (String)vb.getValue(FacesContext.getCurrentInstance()); } } return customizerBean; } public void setCustomizerBean(String customizerBean) { this.customizerBean = customizerBean; } // public ArrayList<DojoEvent> getDojoEvents() { // return this.dojoEvents; // } // // public void addDojoEvent(DojoEvent dojoEvent) { // dojoEvents.add(dojoEvent); // } public String getStructureComponentId() { if (structureComponentId != null) return structureComponentId; ValueBinding _vb = getValueBinding("structureComponentId"); // $NON-NLS-1$ if (_vb != null) return (String) _vb.getValue(getFacesContext()); else return null; } public void setStructureComponentId(String structure) { this.structureComponentId = structure; } public String getOnSortChanged() { if (onSortChanged != null) return onSortChanged; ValueBinding _vb = getValueBinding("onSortChanged"); // $NON-NLS-1$ if (_vb != null) return (String) _vb.getValue(getFacesContext()); else return null; } public void setOnSortChanged(String sortChangedAction) { this.onSortChanged = sortChangedAction; } public String getOnCellClick() { if (null != this.onCellClick) { return this.onCellClick; } ValueBinding _vb = getValueBinding("onCellClick"); //$NON-NLS-1$ if (_vb != null) { return (java.lang.String) _vb.getValue(getFacesContext()); } else { return null; } } public void setOnCellClick(String onCellClick) { this.onCellClick = onCellClick; } public String getOnCellDblClick() { if (null != this.onCellDblClick) { return this.onCellDblClick; } ValueBinding _vb = getValueBinding("onCellDblClick"); //$NON-NLS-1$ if (_vb != null) { return (java.lang.String) _vb.getValue(getFacesContext()); } else { return null; } } public void setOnCellDblClick(String onCellDblClick) { this.onCellDblClick = onCellDblClick; } public boolean isHideColumns() { if (hideColumns != null) return hideColumns; ValueBinding _vb = getValueBinding("hideColumns"); // $NON-NLS-1$ if (_vb != null){ Object val = _vb.getValue(getFacesContext()); if( val instanceof Boolean ){ return (Boolean) val; } } return false; } public void setHideColumns(boolean hideColumns) { this.hideColumns = hideColumns; } public boolean isAlternateRows() { if (null != this.alternateRows) { return this.alternateRows; } ValueBinding _vb = getValueBinding("alternateRows"); //$NON-NLS-1$ if (_vb != null) { Boolean val = (Boolean) _vb.getValue(getFacesContext()); if(val!=null) { return val; } } return false; } public void setAlternateRows(boolean alternateRows) { this.alternateRows = alternateRows; } public boolean isCanBeNarrowMode() { if (null != this.canBeNarrowMode) { return this.canBeNarrowMode; } ValueBinding _vb = getValueBinding("canBeNarrowMode"); //$NON-NLS-1$ if (_vb != null) { Boolean val = (Boolean) _vb.getValue(getFacesContext()); if(val!=null) { return val; } } return false; } public void setCanBeNarrowMode(boolean canBeNarrowMode) { this.canBeNarrowMode = canBeNarrowMode; } // MWD Commenting this out -- see if anybody cares // TODO Remove completely after beta and before IFR1 if no feedback // /** // * @deprecated Use {@link #isShowColumnName4EmptyTitle()} instead // */ // public Boolean getShowColumnName4EmptyTitle() { // return isShowColumnName4EmptyTitle(); // } public boolean isShowColumnNameForEmptyTitle() { if (null != this.showColumnNameForEmptyTitle) { return this.showColumnNameForEmptyTitle; } ValueBinding vb = getValueBinding("showColumnNameForEmptyTitle"); //$NON-NLS-1$ if (vb != null) { Boolean val = (Boolean) vb.getValue(getFacesContext()); if(val!=null) { return val; } } return false; } // MWD Commenting this out -- see if anybody cares // TODO Remove completelt after beta and before IFR1 if no feedback // /** // * @deprecated use {@link #setShowColumnName4EmptyTitle(boolean)} instead. // */ // public void setShowColumnName4EmptyTitle(Boolean showColumnName4EmptyTitle) { // if( null != showColumnName4EmptyTitle ){ // setShowColumnName4EmptyTitle(showColumnName4EmptyTitle.booleanValue()); // } // } public void setShowColumnNameForEmptyTitle(boolean showColumnNameForEmptyTitle) { this.showColumnNameForEmptyTitle = showColumnNameForEmptyTitle; } /* (non-Javadoc) * @see com.ibm.xsp.extlib.component.domino.UIViewComponent#getJsId() */ @Override public String getJsId() { return super.getJsId(); } @Override public void writeActionHandlerScripts(ResponseWriter writer) throws IOException { super.writeActionHandlerScripts(writer); String value = this.getOnSortChanged(); if(StringUtil.isNotEmpty(value)){ this.writeActionHandlerScript(writer, "sortChangedAction", "col", value); // $NON-NLS-1$ $NON-NLS-2$ } value = this.getOnCellClick(); if(StringUtil.isNotEmpty(value)){ this.writeActionHandlerScript(writer, "onCellClick", "ev,ext", value); // $NON-NLS-1$ $NON-NLS-2$ } value = this.getOnCellDblClick(); if(StringUtil.isNotEmpty(value)){ this.writeActionHandlerScript(writer, "onCellDblClick", "ev,ext", value); // $NON-NLS-1$ $NON-NLS-2$ } } @Override public Object saveState(FacesContext context) { Object values[] = new Object[12]; values[0] = super.saveState(context); values[1] = structureComponentId; values[2] = onSortChanged; values[3] = hideColumns; values[4] = alternateRows; values[5] = canBeNarrowMode; values[6] = dynamicView; values[7] = currentView; values[8] = customizerBean; values[9] = showColumnNameForEmptyTitle; values[10] = onCellClick; values[11] = onCellDblClick; return values; } @Override public void restoreState(FacesContext context, Object state) { Object values[] = (Object[]) state; super.restoreState(context, values[0]); this.structureComponentId = (String) values[1]; this.onSortChanged = (String) values[2]; this.hideColumns = (Boolean) values[3]; this.alternateRows = (Boolean) values[4]; this.canBeNarrowMode = (Boolean) values[5]; this.dynamicView = (Boolean) values[6]; this.currentView = (String) values[7]; this.customizerBean = (String) values[8]; this.showColumnNameForEmptyTitle = (Boolean) values[9]; this.onCellClick = (String) values[10]; this.onCellDblClick = (String) values[11]; } // ==================================================================== // Dynamic Columns Management // ==================================================================== @Override public void encodeBegin(FacesContext context) throws IOException { if(dynamicView==null) { dynamicView = isDynamicView(); } if(dynamicView) { updateColumns(context); } super.encodeBegin(context); } protected boolean isDynamicView() { // If at least one column had been added, the we consider that the view is not dynamic if(getChildCount()>0) { List<UIComponent> children = TypedUtil.getChildren(this); for(UIComponent c: children) { if(c instanceof UIListViewColumn) { return false; } } } return true; } protected void updateColumns(FacesContext context) { try { String viewKey=findViewKey(context); if(!StringUtil.equals(viewKey, currentView)) { Customizer bean = loadCustomizationBean(context); clearColumns(context,bean); ViewFactory f = getViewFactory(context,bean); if(f!=null) { createColumns(context,bean,f,ViewDesign.loadView(viewKey)); } this.currentView = viewKey; } } catch(NotesException ex) {} } protected String findViewKey(FacesContext context) throws NotesException { // Find the data store and the view it points to String storeId = getStoreComponentId(); if(StringUtil.isNotEmpty(storeId)) { UIComponent c = FacesUtil.getComponentFor(this, storeId); if(c instanceof UIRestService) { IRestService svc = ((UIRestService)c).getService(); if(svc instanceof DominoViewService) { String databaseName = ((DominoViewService)svc).getDatabaseName(); String viewName = ((DominoViewService)svc).getViewName(); return ViewDesign.getViewKey(databaseName, viewName); } } } return null; } protected Customizer loadCustomizationBean(FacesContext context) { String bean = getCustomizerBean(); if(StringUtil.isNotEmpty(bean)) { return (Customizer)ManagedBeanUtil.getBean(context, bean); } return null; } protected void clearColumns(FacesContext context, Customizer bean) { getChildren().clear(); } protected void createColumns(FacesContext context, Customizer bean, ViewFactory f, View view) { if(bean==null || !bean.createColumns(context, this, f)) { ViewDef viewDef = f.getViewDef(view); if(viewDef!=null) { // The view control already exists, it is simply wrapped into a ControlImpl // We then create the columns and ask the control builder to actually // add the columns to the view panel and call the FacesComponent methods ControlImpl<UIListView> viewControl = new ControlImpl<UIListView>(this); int index = 0; for(Iterator<ColumnDef> it=viewDef.iterateColumns(); it.hasNext(); index++) { ColumnDef colDef = it.next(); IControl viewCol = createColumn(context,bean,index,colDef); viewControl.addChild(viewCol); } ControlBuilder.buildControl(context, viewControl,true); } } if(bean!=null) { bean.afterCreateColumns(context, this); } } protected IControl createColumn(FacesContext context, Customizer bean, int index, ColumnDef colDef) { if(bean!=null) { IControl col = bean.createColumn(context, this, index, colDef); if(col!=null) { return col; } } // Create the column object UIListViewColumn col = new UIListViewColumn(); col.setColumnName(colDef.getName()); col.setColumnTitle(colDef.getTitle()); col.setWidth(String.valueOf(colDef.getWidth())); col.setResponse(colDef.isResponse()); col.setTwistie(colDef.isIndentResponses()); col.setHidden(colDef.isHidden()); col.setCategory(colDef.isCategorized()); boolean isAsc = colDef.isResortAscending(); boolean isDsc = colDef.isResortDescending(); int sort; if( isAsc ){ sort = isDsc ? UIListViewColumn.SORT_BOTH : UIListViewColumn.SORT_ASCENDING; }else{ sort = isDsc ? UIListViewColumn.SORT_DESCENDING : UIListViewColumn.SORT_NONE; } col.setSort( sort ); col.setIcon( colDef.isIcon() ); ControlImpl<UIListViewColumn> cCol = new ControlImpl<UIListViewColumn>(col); if(bean!=null) { bean.afterCreateColumn(context, index, colDef, cCol); } return cCol; } protected ViewFactory getViewFactory(FacesContext context, Customizer bean) { if(bean!=null) { ViewFactory f = bean.getViewFactory(); if(f!=null) { return f; } } return ViewDesign.getDefaultFactory(context); } }