/* * � Copyright IBM Corp. 2010, 2012 * * 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. */ /* * DataIteratorAddRows.java was added 2011-Sep-21. */ package com.ibm.xsp.extlib.actions.client.data; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.el.EvaluationException; import javax.faces.el.MethodNotFoundException; import javax.faces.el.ValueBinding; import com.ibm.commons.util.StringUtil; import com.ibm.commons.util.io.json.JsonGenerator; import com.ibm.commons.util.io.json.JsonJavaFactory; import com.ibm.commons.util.io.json.JsonJavaObject; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.actions.client.AbstractClientSimpleAction; import com.ibm.xsp.ajax.AjaxUtil; import com.ibm.xsp.component.FacesDataIterator; import com.ibm.xsp.component.UIDataEx; import com.ibm.xsp.context.FacesContextEx; import com.ibm.xsp.extlib.component.data.FacesDataIteratorAjax; import com.ibm.xsp.extlib.resources.ExtLibResources; import com.ibm.xsp.util.FacesUtil; public class DataIteratorAddRows extends AbstractClientSimpleAction { // Note, to keep with the naming convention this class should // be named DataIteratorAddRowsAction (i.e. with the suffix ..Action) // But it has already been shipped in 8.5.3UpgradePack1 // with the current name, so we cannot change it as it would break // existing applications. public static final String DISABLED_FORMAT_HIDE = "hide"; //$NON-NLS-1$ public static final String DISABLED_FORMAT_LINK = "link"; //$NON-NLS-1$ public static final String DISABLED_FORMAT_TEXT = "text"; //$NON-NLS-1$ public static final String DISABLED_FORMAT_AUTO = "auto"; //$NON-NLS-1$ private String _for; private Integer _rowCount; private String _disableId; private Boolean _state; private String _disabledFormat; public DataIteratorAddRows() { super(); } public String getFor() { if (_for == null) { ValueBinding vb = getValueBinding("for"); //$NON-NLS-1$ if (vb != null) { return (String) vb.getValue(getFacesContext()); } } return _for; } public void setFor(String _for) { this._for = _for; } public int getRowCount() { if (null != this._rowCount) { return this._rowCount; } ValueBinding vb = getValueBinding("rowCount"); //$NON-NLS-1$ if (vb != null) { Integer val = (Integer) vb.getValue(getFacesContext()); if(val!=null) { return val; } } return 0; } public void setRowCount(int rows) { this._rowCount = rows; } public String getDisableId() { if (_disableId == null) { ValueBinding vb = getValueBinding("disableId"); //$NON-NLS-1$ if (vb != null) { return (String) vb.getValue(getFacesContext()); } } return _disableId; } public void setDisableId(String disableId) { this._disableId = disableId; } /** * @return the disabledFormat */ public String getDisabledFormat() { if(_disabledFormat!=null) { return _disabledFormat; } ValueBinding vb = getValueBinding("disabledFormat"); //$NON-NLS-1$ if(vb!=null) { return (String)vb.getValue(getFacesContext()); } return null; } /** * @param disabledFormat the disabledFormat to set */ public void setDisabledFormat(String disabledFormat) { this._disabledFormat = disabledFormat; } public boolean isState() { if (null != this._state) { return this._state; } ValueBinding vb = getValueBinding("state"); //$NON-NLS-1$ if (vb != null) { Boolean val = (Boolean) vb.getValue(getFacesContext()); if(val!=null) { return val; } } return false; } public void setState(boolean state) { this._state = state; } @Override public Object saveState(FacesContext context) { Object[] state = new Object[6]; state[0] = super.saveState(context); state[1] = _for; state[2] = _rowCount; state[3] = _disableId; state[4] = _disabledFormat; state[5] = _state; return state; } @Override public void restoreState(FacesContext context, Object value) { Object[] values = (Object[])value; super.restoreState(context, values[0]); _for = (String)values[1]; _rowCount = (Integer)values[2]; _disableId = (String)values[3]; _disabledFormat = (String) values[4]; _state = (Boolean)values[5]; } @Override public Object invoke(FacesContext context, Object[] params) throws EvaluationException, MethodNotFoundException { FacesDataIterator dt = findDataIterator(); String linkId = null; String id = getDisableId(); if(StringUtil.isNotEmpty(id)) { UIComponent l = FacesUtil.getComponentFor(getComponent(), id); if(l!=null) { linkId = l.getClientId(context); } } String disabledFormat = getDisabledFormat(); disabledFormat = computeDisabledFormat(context, disabledFormat, /*rendererDefaultFormat*/null); return generateJavaScript(context, dt, getRowCount(), isState(), linkId, disabledFormat); } protected FacesDataIterator findDataIterator() { String id = getFor(); if(StringUtil.isNotEmpty(id)) { UIComponent c = FacesUtil.getComponentFor(getComponent(), id); if(c==null) { throw new FacesExceptionEx(null,"Component {0} does not exist",id); // $NLX-DataIteratorAddRows.Component0doesnotexist-1$ } if(!(c instanceof FacesDataIterator)) { throw new FacesExceptionEx(null,"Component {0} is not a data iterator",id); // $NLX-DataIteratorAddRows.Component0isnotadataiterator-1$ } return (FacesDataIterator)c; } for(UIComponent c=getComponent(); c!=null; c=c.getParent()) { if(c instanceof FacesDataIterator) { return (FacesDataIterator)c; } } throw new FacesExceptionEx(null,"The simple action cannot find a data iterator"); // $NLX-DataIteratorAddRows.Thesimpleactioncannotfindadataite-1$ } /** * @param context * @param dt * @param rowCount * @param state * @param linkId * @return * @throws EvaluationException * @throws MethodNotFoundException * @deprecated use the other generate.. method instead, * first calling {@link #computeDisabledFormat(FacesContext, String, String)} * to compute the last parameter for * {@link #generateJavaScript(FacesContext, FacesDataIterator, int, boolean, String, String)}. */ public static String generateJavaScript(FacesContext context, FacesDataIterator dt, int rowCount, boolean state, String linkId) throws EvaluationException, MethodNotFoundException { String computedDisabledFormat = computeDisabledFormat(context, null, null); return generateJavaScript(context, dt, rowCount, state, linkId, computedDisabledFormat); } /** * * @param context * @param dt * @param rowCount * @param state * @param linkId * @param computedDisabledFormat the result of a call to {@link #computeDisabledFormat(FacesContext, String, String)}; * @return * @throws EvaluationException * @throws MethodNotFoundException */ public static String generateJavaScript(FacesContext context, FacesDataIterator dt, int rowCount, boolean state, String linkId, String computedDisabledFormat) throws EvaluationException, MethodNotFoundException { StringBuilder b = new StringBuilder(256); UIComponent c = (UIComponent)dt; // Add the dojo module ExtLibResources.addEncodeResource(context, ExtLibResources.extlibDataIterator); // And generate the piece of script String id = (c instanceof FacesDataIteratorAjax) ? ((FacesDataIteratorAjax)c).getAjaxContainerClientId(context) : c.getClientId(context); String url = AjaxUtil.getAjaxUrl(context, c, UIDataEx.AJAX_GETROWS, c.getClientId(context)); url = context.getExternalContext().encodeActionURL(url); int first = dt.getFirst()+dt.getRows(); int count = rowCount; if(count<=0) { // For SPR#MKEE8MHELJ, default to 30 rows // instead of to dt.getRows(), to prevent duplicating // the number of rows displayed on every click. count = UIDataEx.DEFAULT_ROWS_PER_PAGE; } // partial workaround for SPR#LHEY8LNDZS, problem in the xpage runtime. // The UIDataEx and UIDataIterator classes can't handle it when // the number of rows to be added is < the rows property - they // return too few rows. The client-side XSP.appendRows method // thinks that, since too few rows are present, all the rows // in the data set have been displayed, so it removes // the "Show more" link, even though not all rows have been shown. count = Math.min(count, dt.getRows()); try { b.append("XSP.appendRows("); //$NON-NLS-1$ JsonJavaObject jo = new JsonJavaObject(); jo.putString("id", id); //$NON-NLS-1$ jo.putString("url", url); //$NON-NLS-1$ jo.putInt("first", first); //$NON-NLS-1$ jo.putInt("count", count); //$NON-NLS-1$ jo.putBoolean("state", state); //$NON-NLS-1$ if( null != linkId ){ jo.putString("linkId", linkId); //$NON-NLS-1$ if( !DISABLED_FORMAT_TEXT.equals(computedDisabledFormat) ){ jo.putString("linkDisabledFormat", computedDisabledFormat); //$NON-NLS-1$ } } JsonGenerator.toJson(JsonJavaFactory.instance,b,jo,true); b.append(");"); //$NON-NLS-1$ } catch(Exception e) { throw new FacesExceptionEx(e); } return b.toString(); } /** * Returns an exact string that is one of {@link #DISABLED_FORMAT_HIDE}, * {@link #DISABLED_FORMAT_LINK} or {@link #DISABLED_FORMAT_TEXT}, * having consulted the xsp.properties options for the default value. * @param context * @param disabledFormatInXPageSource * @param rendererDefaultFormat * @return */ public static String computeDisabledFormat(FacesContext context, String disabledFormatInXPageSource, String rendererDefaultFormat ){ String formatTypeAsString; if( StringUtil.isNotEmpty(disabledFormatInXPageSource) ){ formatTypeAsString = disabledFormatInXPageSource; }else{ // Note, if there are customer complaints about // the change in default disabledFormat, then publicize // this xsp.properties option. String xspPropertiesOption = "extlib.addrows.disabledFormat"; //$NON-NLS-1$ String applicationDefaultFormat = ((FacesContextEx)context).getProperty(xspPropertiesOption); if( StringUtil.isNotEmpty(applicationDefaultFormat) ){ formatTypeAsString = applicationDefaultFormat; }else{ if( StringUtil.isNotEmpty(rendererDefaultFormat) ){ formatTypeAsString = rendererDefaultFormat; }else{ formatTypeAsString = DISABLED_FORMAT_TEXT; } } } if( DISABLED_FORMAT_AUTO.equals(formatTypeAsString) ){ formatTypeAsString = DISABLED_FORMAT_TEXT; } if (DISABLED_FORMAT_LINK.equals(formatTypeAsString) ) { return DISABLED_FORMAT_LINK; } else if(DISABLED_FORMAT_HIDE.equals(formatTypeAsString)){ return DISABLED_FORMAT_HIDE; }else{ return DISABLED_FORMAT_TEXT; } } }