001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.layout;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
020import org.kuali.rice.krad.uif.CssConstants;
021import org.kuali.rice.krad.uif.UifConstants;
022import org.kuali.rice.krad.uif.UifPropertyPaths;
023import org.kuali.rice.krad.uif.component.DataBinding;
024import org.kuali.rice.krad.uif.container.CollectionGroup;
025import org.kuali.rice.krad.uif.control.Control;
026import org.kuali.rice.krad.uif.control.ValueConfiguredControl;
027import org.kuali.rice.krad.uif.field.InputField;
028import org.kuali.rice.krad.uif.field.Field;
029import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
030import org.kuali.rice.krad.uif.element.Pager;
031import org.kuali.rice.krad.util.KRADUtils;
032
033import java.util.List;
034
035/**
036 * Utilities for collection layout managers
037 *
038 * @author Kuali Rice Team (rice.collab@kuali.org)
039 */
040public class CollectionLayoutUtils {
041
042    public static void prepareSelectFieldForLine(Field selectField, CollectionGroup collectionGroup, String lineBindingPath,
043            Object line) {
044        // if select property name set use as property name for select field
045        String selectPropertyName = collectionGroup.getLineSelectPropertyName();
046        if (StringUtils.isNotBlank(selectPropertyName)) {
047            // if select property contains form prefix, will bind to form and not each line
048            if (selectPropertyName.startsWith(UifConstants.NO_BIND_ADJUST_PREFIX)) {
049                selectPropertyName = StringUtils.removeStart(selectPropertyName, UifConstants.NO_BIND_ADJUST_PREFIX);
050                ((DataBinding) selectField).getBindingInfo().setBindingName(selectPropertyName);
051                ((DataBinding) selectField).getBindingInfo().setBindToForm(true);
052            } else {
053                ((DataBinding) selectField).getBindingInfo().setBindingName(selectPropertyName);
054                ((DataBinding) selectField).getBindingInfo().setBindByNamePrefix(lineBindingPath);
055            }
056        } else {
057            // select property name not given, use UifFormBase#selectedCollectionLines
058            String collectionLineKey = KRADUtils.translateToMapSafeKey(
059                    collectionGroup.getBindingInfo().getBindingPath());
060            String selectBindingPath = UifPropertyPaths.SELECTED_COLLECTION_LINES + "['" + collectionLineKey + "']";
061
062            ((DataBinding) selectField).getBindingInfo().setBindingName(selectBindingPath);
063            ((DataBinding) selectField).getBindingInfo().setBindToForm(true);
064        }
065
066        setControlValueToLineIdentifier(selectField, line, lineBindingPath);
067    }
068
069    protected static void setControlValueToLineIdentifier(Field selectField, Object line, String lineBindingPath) {
070        if (selectField instanceof InputField) {
071            Control selectControl = ((InputField) selectField).getControl();
072
073            if (selectControl != null) {
074                selectControl.addStyleClass(CssConstants.Classes.SELECT_FIELD_STYLE_CLASS);
075
076                if (selectControl instanceof ValueConfiguredControl) {
077                    String lineIdentifier
078                            = KRADServiceLocatorWeb.getLegacyDataAdapter().getDataObjectIdentifierString(line);
079
080                    if (StringUtils.isBlank(lineIdentifier)) {
081                        lineIdentifier = lineBindingPath;
082                    }
083
084                    ((ValueConfiguredControl) selectControl).setValue(lineIdentifier);
085                }
086            }
087        }
088    }
089
090    /**
091     * Setup a pagerWidget's values for numberOfPages and currentPage, based on the collection size, displayStart,
092     * and displayLength
093     *
094     * @param pagerWidget the Pager to setup
095     * @param collectionGroup  the collectionGroup which uses this Pager
096     * @param model the current model
097     */
098    protected static void setupPagerWidget(Pager pagerWidget, CollectionGroup collectionGroup, Object model){
099        List<Object> modelCollection = ObjectPropertyUtils.getPropertyValue(model,
100                        collectionGroup.getBindingInfo().getBindingPath());
101
102        // The size of the collection divided by the pageLength is used to determine the number of pages for
103        // the pager component (ceiling is used if there is not a full page left over in the division)
104        if (modelCollection != null) {
105            double pages = (double) modelCollection.size() / (double) collectionGroup.getDisplayLength();
106            pagerWidget.setNumberOfPages((int) Math.ceil(pages));
107        } else {
108            pagerWidget.setNumberOfPages(1);
109        }
110
111        // By using displayStart, currentPage can be determined, the displayLength is added here before division,
112        // because the pager is 1-based
113        int currentPage = (collectionGroup.getDisplayStart() + collectionGroup.getDisplayLength()) / collectionGroup
114                .getDisplayLength();
115        pagerWidget.setCurrentPage(currentPage);
116
117        if (StringUtils.isBlank(pagerWidget.getLinkScript())){
118            pagerWidget.setLinkScript("retrieveCollectionPage(this, '" + collectionGroup.getId() + "');");
119        }
120    }
121}