001/*
002 * The Kuali Financial System, a comprehensive financial management system for higher education.
003 * 
004 * Copyright 2005-2014 The Kuali Foundation
005 * 
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU Affero General Public License as
008 * published by the Free Software Foundation, either version 3 of the
009 * License, or (at your option) any later version.
010 * 
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU Affero General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Affero General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.kuali.kfs.sys.document.web.renderers;
020
021import java.io.IOException;
022import java.util.List;
023
024import javax.servlet.jsp.JspException;
025import javax.servlet.jsp.JspWriter;
026import javax.servlet.jsp.PageContext;
027import javax.servlet.jsp.tagext.Tag;
028
029import org.apache.commons.lang.StringUtils;
030import org.kuali.kfs.sys.KFSConstants;
031import org.kuali.kfs.sys.document.web.AccountingLineViewAction;
032import org.kuali.rice.kns.web.taglib.html.KNSImageTag;
033
034/**
035 * Renders an action for the accounting line view.
036 */
037public class ActionsRenderer implements Renderer {
038    private List<AccountingLineViewAction> actions;
039    private KNSImageTag actionButton = new KNSImageTag();
040    private int tabIndex;
041    private String postButtonSpacing;
042    private String tagBeginning;
043    private String tagEnding;
044    
045    /**
046     * Constructs a ActionsRenderer, which sets values on the actionButton tag that never change
047     */
048    public ActionsRenderer() {
049        actionButton.setStyleClass("tinybutton"); // this never changes
050    }
051
052    /**
053     * 
054     * @see org.kuali.kfs.sys.document.web.renderers.Renderer#clear()
055     */
056    public void clear() {
057        actions = null;
058        
059        resetButton();
060        actionButton.setPageContext(null);
061        actionButton.setParent(null);
062    }
063    
064    /**
065     * Clears out changing values the action button tag
066     */
067    protected void resetButton() {
068        actionButton.setProperty(null);
069        actionButton.setSrc(null);
070        actionButton.setTitle(null);
071        actionButton.setAlt(null);
072        actionButton.setTabindex(null);
073    }
074
075    /**
076     * 
077     * @see org.kuali.kfs.sys.document.web.renderers.Renderer#render(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag)
078     */
079    public void render(PageContext pageContext, Tag parentTag) throws JspException {
080        actionButton.setPageContext(pageContext);
081        actionButton.setParent(parentTag);
082        JspWriter out = pageContext.getOut();
083        
084        try {
085            if (actions != null && actions.size() > 0) {
086                out.write(this.getTagBeginning());
087                for (AccountingLineViewAction action : actions) {
088                    renderAction(action);
089                    out.write(this.getPostButtonSpacing());
090                }
091                out.write(this.getTagEnding());
092            } 
093            else {
094                out.write(buildNonBreakingSpace());
095            }
096        }
097        catch (IOException ioe) {
098            throw new JspException("Difficulty rendering actions block", ioe);
099        }
100    }
101    
102    /**
103     * Renders a single action, using the action button
104     * @param action the action to render
105     * @throws JspException thrown if the actionButton cannot uphold its duties to render the 
106     */
107    protected void renderAction(AccountingLineViewAction action) throws JspException {
108        actionButton.setProperty(KFSConstants.DISPATCH_REQUEST_PARAMETER+"."+action.getActionMethod());
109        actionButton.setSrc(action.getImageName());
110        actionButton.setTitle(action.getActionLabel());
111        actionButton.setAlt(action.getActionLabel());
112        if (!StringUtils.isBlank(getTabIndex())) {
113            actionButton.setTabindex(getTabIndex());
114        }
115        actionButton.doStartTag();
116        actionButton.doEndTag();
117        resetButton();
118    }
119    
120    /**
121     * Builds the opening of the centering div tag
122     * @return the opening of the centering div tag in HTML
123     */
124    protected String buildCenteringDivBeginning() {
125        return "<div style=\"text-align: center;\">";
126    }
127    
128    /**
129     * Builds the close of the centering div tag
130     * @return the close of the centering div tag in HTML
131     */
132    protected String buildCenteringDivEnding() {
133        return "</div>";
134    }
135    
136    /**
137     * Builds spacing for after the button is displayed
138     * @return a String of HTML that will space after the button
139     */
140    public String getPostButtonSpacing() {
141        return postButtonSpacing == null ? "<br />" : postButtonSpacing;
142    }
143    
144    /**
145     * Sets the postButtonSpacing attribute value.
146     * @param postButtonSpacing The postButtonSpacing to set.
147     */
148    public void setPostButtonSpacing(String postButtonSpacing) {
149        this.postButtonSpacing = postButtonSpacing;
150    }
151
152    /**
153     * Gets the action attribute. 
154     * @return Returns the action.
155     */
156    public List<AccountingLineViewAction> getActions() {
157        return actions;
158    }
159
160    /**
161     * Sets the action attribute value.
162     * @param action The action to set.
163     */
164    public void setActions(List<AccountingLineViewAction> actions) {
165        this.actions = actions;
166    }
167
168    /**
169     * Sets the tab index for the action
170     * @param tabIndex the tab index to set
171     */
172    public void setTabIndex(int tabIndex) {
173        this.tabIndex = tabIndex;   
174    }
175    
176    /**
177     * Retrieves the set tab index as a String, or, if the tabIndex was never set, returns a null
178     * @return the tab index as a String or null
179     */
180    protected String getTabIndex() {
181        if (tabIndex > -1) return Integer.toString(tabIndex); 
182        return null;
183    }
184    
185    /**
186     * @return the HTML for a non-breaking space, so the box isn't all empty
187     */
188    protected String buildNonBreakingSpace() {
189        return "&nbsp;";
190    }
191
192    /**
193     * Gets the tagBeginning attribute. 
194     * @return Returns the tagBeginning.
195     */
196    public String getTagBeginning() {
197        return tagBeginning == null ? this.buildCenteringDivBeginning() : tagBeginning;
198    }
199
200    /**
201     * Sets the tagBeginning attribute value.
202     * @param tagBeginning The tagBeginning to set.
203     */
204    public void setTagBeginning(String tagBeginning) {
205        this.tagBeginning = tagBeginning;
206    }
207
208    /**
209     * Gets the tagEnding attribute. 
210     * @return Returns the tagEnding.
211     */
212    public String getTagEnding() {
213        return tagEnding == null ? this.buildCenteringDivEnding() : tagEnding;
214    }
215
216    /**
217     * Sets the tagEnding attribute value.
218     * @param tagEnding The tagEnding to set.
219     */
220    public void setTagEnding(String tagEnding) {
221        this.tagEnding = tagEnding;
222    }
223}