/* * Copyright 2011 PrimeFaces Extensions. * * 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. * * $Id: PreRenderCommandListener.java 470 2011-11-22 19:54:13Z ovaraksin@googlemail.com $ */ package org.primefaces.extensions.component.masterdetail; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.el.ValueExpression; import javax.faces.FacesException; import javax.faces.component.UICommand; import javax.faces.component.UIComponent; import javax.faces.component.UIParameter; import javax.faces.context.FacesContext; import javax.faces.event.ComponentSystemEvent; import javax.faces.event.ComponentSystemEventListener; /** * {@link ComponentSystemEventListener} for an <code>UICommand</code> component. * * @author Oleg Varaksin / last modified by $Author: ovaraksin@googlemail.com $ * @version $Revision: 470 $ */ public class PreRenderCommandListener implements ComponentSystemEventListener, Serializable { private static final long serialVersionUID = 20111121L; @Override public void processEvent(final ComponentSystemEvent event) { UICommand source = (UICommand) event.getComponent(); // find master detail component MasterDetail masterDetail = findMasterDetail(source); if (masterDetail == null) { throw new FacesException("MasterDetail was not found. SelectDetailLevel can be only used inside of MasterDetail."); } // find master detail level component MasterDetailLevel masterDetailLevel = findMasterDetailLevel(source); if (masterDetailLevel == null) { throw new FacesException( "MasterDetailLevel was not found. SelectDetailLevel can be only used inside of MasterDetailLevel."); } final FacesContext fc = FacesContext.getCurrentInstance(); final String masterDetailClientId = masterDetail.getClientId(fc); // attach parameters dynamically // required basic parameters addUIParameter(fc, source, masterDetailClientId + MasterDetail.SELECT_DETAIL_REQUEST, true); addUIParameter(fc, source, masterDetailClientId + MasterDetail.CURRENT_LEVEL, masterDetailLevel.getLevel()); // selected level ValueExpression selectedLevelVE = (ValueExpression) source.getAttributes().get(MasterDetail.SELECTED_LEVEL_VALUE_EXPRESSION); Object selectedLevel = selectedLevelVE != null ? selectedLevelVE.getValue(fc.getELContext()) : null; if (selectedLevel != null) { addUIParameter(fc, source, masterDetailClientId + MasterDetail.SELECTED_LEVEL, selectedLevel); } else { removeUIParameter(source, masterDetailClientId + MasterDetail.SELECTED_LEVEL); } // selected step ValueExpression selectedStepVE = (ValueExpression) source.getAttributes().get(MasterDetail.SELECTED_STEP_VALUE_EXPRESSION); Object selectedStep = selectedStepVE != null ? selectedStepVE.getValue(fc.getELContext()) : null; if (selectedStep != null) { addUIParameter(fc, source, masterDetailClientId + MasterDetail.SELECTED_STEP, selectedStep); } else { removeUIParameter(source, masterDetailClientId + MasterDetail.SELECTED_STEP); } // skip processing flag Boolean skipProcessing = (Boolean) source.getAttributes().get(MasterDetail.SKIP_PROCESSING); if ((skipProcessing != null && skipProcessing) || source.isImmediate()) { addUIParameter(fc, source, masterDetailClientId + MasterDetail.SKIP_PROCESSING_REQUEST, true); } else { removeUIParameter(source, masterDetailClientId + MasterDetail.SKIP_PROCESSING_REQUEST); } ValueExpression contextValueVE = (ValueExpression) source.getAttributes().get(MasterDetail.CONTEXT_VALUE_VALUE_EXPRESSION); if (contextValueVE == null) { return; } @SuppressWarnings("unchecked") Map<String, Object> contextValues = (Map<String, Object>) masterDetailLevel.getAttributes().get(MasterDetail.CONTEXT_VALUES); if (contextValues == null) { contextValues = new HashMap<String, Object>(); } // resolve context value and make it available in processUpdates() of MasterDetail component Object contextValue = contextValueVE.getValue(fc.getELContext()); if (contextValue != null) { contextValues.put("contextValue_" + source.getClientId(fc), contextValue); } else { contextValues.remove("contextValue_" + source.getClientId(fc)); } masterDetailLevel.getAttributes().put(MasterDetail.CONTEXT_VALUES, contextValues); } private static MasterDetail findMasterDetail(final UIComponent component) { UIComponent parent = component.getParent(); while (parent != null) { if (parent instanceof MasterDetail) { return (MasterDetail) parent; } parent = parent.getParent(); } return null; } private MasterDetailLevel findMasterDetailLevel(final UIComponent component) { UIComponent parent = component.getParent(); while (parent != null) { if (parent instanceof MasterDetailLevel) { return (MasterDetailLevel) parent; } parent = parent.getParent(); } return null; } private void addUIParameter(final FacesContext fc, final UIComponent source, final String paramName, final Object paramValue) { UIParameter uiParameter = null; for (UIComponent child : source.getChildren()) { if (child instanceof UIParameter && paramName.equals(((UIParameter) child).getName())) { // update value ((UIParameter) child).setValue(paramValue); return; } } uiParameter = new UIParameter(); uiParameter.setId(fc.getViewRoot().createUniqueId(fc, null)); uiParameter.setName(paramName); uiParameter.setValue(paramValue); source.getChildren().add(uiParameter); } private void removeUIParameter(final UIComponent source, final String paramName) { List<UIComponent> childs = source.getChildren(); if (childs == null || childs.isEmpty()) { return; } for (UIComponent child : childs) { if (child instanceof UIParameter && paramName.equals(((UIParameter) child).getName())) { childs.remove(child); break; } } } }