001package org.kuali.ole.krad;
002
003import java.text.DateFormat;
004import java.text.Format;
005import java.text.NumberFormat;
006import java.util.ArrayList;
007import java.util.Date;
008import java.util.List;
009
010import org.apache.commons.lang3.StringUtils;
011import org.apache.log4j.Logger;
012import org.kuali.rice.krad.uif.UifConstants;
013import org.kuali.rice.krad.uif.component.Component;
014import org.kuali.rice.krad.uif.container.Group;
015import org.kuali.rice.krad.uif.container.PageGroup;
016import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
017import org.kuali.rice.krad.web.form.UifFormBase;
018import org.springframework.web.context.request.RequestAttributes;
019import org.springframework.web.context.request.RequestContextHolder;
020
021/**
022 * Utility class for supporting low-level KRAD optimizations.
023 */
024public final class OleComponentUtils {
025
026        private static final Logger LOG = Logger.getLogger(OleComponentUtils.class);
027
028        private static ThreadLocal<Format> CURRENCY_FORMAT = new ThreadLocal<Format>() {
029                @Override
030                protected Format initialValue() {
031                        return NumberFormat.getCurrencyInstance();
032                }
033        };
034
035        private static ThreadLocal<Format> DATE_FORMAT = new ThreadLocal<Format>() {
036                @Override
037                protected Format initialValue() {
038                        return DateFormat.getDateInstance();
039                }
040        };
041
042        /**
043         * Gets the KRAD model for the active request.
044         * 
045         * @return KRAD model
046         */
047        public static Object getModel() {
048                RequestAttributes attr = RequestContextHolder.getRequestAttributes();
049                if (attr == null) {
050                        return null;
051                } else {
052                        return attr.getAttribute(UifConstants.REQUEST_FORM,
053                                        RequestAttributes.SCOPE_REQUEST);
054                }
055        }
056
057        /**
058         * Filters items for a group that also implements OleComponentUtils.
059         */
060        public static List<? extends Component> filterItems(
061                        List<? extends Component> srcitems) {
062                if (srcitems == null) {
063                        return null;
064                }
065
066                Object model = getModel();
067                if (model == null) {
068                        return srcitems;
069                } else {
070                        LOG.debug("Filtering based on " + model);
071                }
072
073                List<Component> items = new ArrayList<Component>();
074                filterloop: for (Component itemComponent : srcitems) {
075
076                        // Filter out OleComponent instances matching true
077                        if (itemComponent instanceof OleComponent) {
078                                OleComponent oleComp = (OleComponent) itemComponent;
079                                String filterProp = oleComp.getFilterModelProperty();
080                                Object filterVal = filterProp == null ? null
081                                                : ObjectPropertyUtils.getPropertyValue(model,
082                                                                filterProp);
083                                if (filterVal instanceof String)
084                                        filterVal = Boolean.parseBoolean((String) filterVal);
085                                if (filterVal == null && filterProp != null)
086                                        filterVal = Boolean.TRUE;
087                                if (Boolean.TRUE.equals(filterVal)) {
088                                        LOG.debug("Omitting " + itemComponent.getClass() + " "
089                                                        + itemComponent.getId() + ", " + filterProp
090                                                        + " is true");
091                                        continue filterloop;
092                                } else {
093                                        LOG.debug("Keeping " + itemComponent.getClass() + " "
094                                                        + itemComponent.getId() + ", " + filterProp
095                                                        + " is true");
096                                }
097                        }
098
099                        items.add((Component) itemComponent.copy());
100                }
101
102                return items;
103        }
104
105        /**
106         * Filters items for a view to remove non-current pages.
107         */
108        public static List<? extends Group> filterCurrentPage(String currentPageId,
109                        List<? extends Group> srcitems) {
110                if (srcitems == null) {
111                        return null;
112                }
113
114                Object model = getModel();
115                if (model == null || !(model instanceof UifFormBase))
116                        return srcitems;
117
118                if (StringUtils.isEmpty(currentPageId))
119                        return srcitems;
120
121                LOG.debug("Filtering view pages based on " + model + ", pageId = "
122                                + currentPageId);
123
124                List<Group> items = new ArrayList<Group>();
125                for (Group group : srcitems) {
126                        String compId = group.getId();
127
128                        // Filter out OleComponent instances matching true
129                        if ((group instanceof PageGroup) && !currentPageId.equals(compId)) {
130                                LOG.debug("Omitting " + compId + ", not current page");
131                                continue;
132                        } else
133                                LOG.debug("Keeping " + compId
134                                                + ", current page or not a PageGroup");
135
136                        items.add((Group) group.copy());
137                }
138
139                return items;
140        }
141
142        /**
143         * Convenience method for converting {@link Number} to currency string
144         * representation with minimal overhead.
145         * 
146         * <p>
147         * Intended for use in KRAD SpEL expressions, for example:
148         * </p>
149         * 
150         * <pre>
151         * @{T(org.kuali.ole.krad.OleComponentUtils).formatAsCurrency(anAmount)}
152         * </pre>
153         * 
154         * @param amount
155         *            Currency amount
156         * @return formatted currency string
157         */
158        public static String formatAsCurrency(Number amount) {
159                return amount == null ? "" : CURRENCY_FORMAT.get().format(amount);
160        }
161
162        /**
163         * Convenience method for converting {@link Date} to a string
164         * representation with minimal overhead.
165         * 
166         * <p>
167         * Intended for use in KRAD SpEL expressions, for example:
168         * </p>
169         * 
170         * <pre>
171         * @{T(org.kuali.ole.krad.OleComponentUtils).formatDate(aDate)}
172         * </pre>
173         * 
174         * @param date date
175         * @return formatted date string
176         */
177        public static String formatDate(Date date) {
178                return date == null ? "" : DATE_FORMAT.get().format(date);
179        }
180
181        private OleComponentUtils() {
182        }
183
184}
185