View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.element;
17  
18  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTags;
21  import org.kuali.rice.krad.uif.CssConstants;
22  import org.kuali.rice.krad.uif.UifConstants;
23  import org.kuali.rice.krad.uif.util.LifecycleElement;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  /**
29   * Element which shows a visual progress bar based on percentageValue passed in or segmentPercentages passed in
30   *
31   * @author Kuali Rice Team (rice.collab@kuali.org)
32   */
33  @BeanTags({@BeanTag(name = "progressBar-bean", parent = "Uif-ProgressBar"),
34          @BeanTag(name = "progressBarVertical-bean", parent = "Uif-ProgressBar-Vertical")})
35  public class ProgressBar extends ContentElementBase {
36      private static final long serialVersionUID = -2643777398164666573L;
37  
38      private Integer percentComplete;
39  
40      private List<Integer> segmentPercentages;
41      private List<String> segmentSizes;
42      private List<String> segmentClasses;
43  
44      private boolean vertical;
45  
46      public ProgressBar() {
47          segmentSizes = new ArrayList<String>();
48          segmentClasses = new ArrayList<String>();
49          this.setRole(UifConstants.AriaRoles.PROGRESS_BAR);
50      }
51  
52      /**
53       * Sets the appropriate classes and bar widths based on values in percentComplete or segmentPercentages
54       *
55       * {@inheritDoc}
56       */
57      @Override
58      public void performFinalize(Object model, LifecycleElement parent) {
59          super.performFinalize(model, parent);
60  
61          // Css property used by bars based on vertical flag (width or height)
62          String cssDimension = CssConstants.WIDTH;
63          if (vertical) {
64              cssDimension = CssConstants.HEIGHT;
65          }
66  
67          boolean explicitlySetSizes = segmentPercentages != null && !getSegmentPercentages().isEmpty();
68  
69          // Simply use the percentage if set, and no explicitly set sizes (use those instead if set)
70          if (!explicitlySetSizes && percentComplete != null) {
71              segmentClasses = new ArrayList<String>();
72  
73              // Add appropriate style string based on dimension and percentage
74              segmentSizes.add(cssDimension + percentComplete + "%");
75              segmentClasses.add(
76                      CssConstants.ProgressBar.PROGRESS_BAR + " " + CssConstants.ProgressBar.SUCCESS_PROGRESS_BAR);
77  
78              this.setTitle(percentComplete.toString() + "%");
79  
80              // Set aria attributes
81              this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_MIN, "0");
82              this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_MAX, "100");
83              this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_NOW, percentComplete.toString());
84          } else if (explicitlySetSizes && !(this instanceof StepProgressBar)) {
85              if (segmentClasses == null || segmentClasses.size() != segmentPercentages.size()) {
86                  throw new RuntimeException(
87                          "If segmentPercentages are set on a base ProgressBar type, segmentClasses must "
88                                  + "also be explicitly set and contain the same number of items");
89              }
90  
91              // Add appropriate style string based on dimension and percentage
92              percentComplete = 0;
93              for (int index = 0; index < segmentPercentages.size(); index++) {
94                  segmentSizes.add(cssDimension + segmentPercentages.get(index) + "%");
95                  percentComplete = percentComplete + segmentPercentages.get(index);
96              }
97  
98              // Set aria attributes
99              this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_MIN, "0");
100             this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_MAX, "100");
101             this.addAriaAttribute(UifConstants.AriaAttributes.VALUE_NOW, percentComplete.toString());
102         }
103 
104     }
105 
106     /**
107      * Percent value complete used to visually indicate this ProgressBar's completeness
108      *
109      * @return the Integer value representing perecent complete for this ProgressBar
110      */
111     @BeanTagAttribute(name = "percentComplete")
112     public Integer getPercentComplete() {
113         return percentComplete;
114     }
115 
116     /**
117      * @see ProgressBar#getPercentComplete()
118      */
119     public void setPercentComplete(Integer percentComplete) {
120         this.percentComplete = percentComplete;
121     }
122 
123     /**
124      * List of bar classes to use for each bar "section" for coloring or styling purposes, only settable for
125      * full configuration purposes and should not normally be set
126      *
127      * <p>These are normally set automatically by the framework, but can be explicitly defined if segmentPercentages
128      * are also explicitly set.  When setting segmentClasses, it's list size MUST equal segmentPercentages.</p>
129      *
130      * @return the list of bar classes
131      */
132     @BeanTagAttribute(name = "segmentClasses", type = BeanTagAttribute.AttributeType.LISTVALUE)
133     public List<String> getSegmentClasses() {
134         return segmentClasses;
135     }
136 
137     /**
138      * @see org.kuali.rice.krad.uif.element.ProgressBar#getSegmentClasses()
139      */
140     public void setSegmentClasses(List<String> segmentClasses) {
141         this.segmentClasses = segmentClasses;
142     }
143 
144     /**
145      * The percentage each bar "section" will take up on the progress bar, only settable for
146      * full configuration purposes and should not normally be set
147      *
148      * <p>This is normally automatically set by the framework with no additional configuration.
149      * When explicitly set for ProgressBars, barClases should ALSO be set
150      * (this however is optional for StepProgressBars).
151      * The percentages effects how much space each section will take up on the bar and the total should not
152      * exceed 100.  For StepProgressBars, this list's size must equal the number of steps.</p>
153      *
154      * @return the bar percentages to use
155      */
156     @BeanTagAttribute(name = "segmentPercentages", type = BeanTagAttribute.AttributeType.LISTVALUE)
157     public List<Integer> getSegmentPercentages() {
158         return segmentPercentages;
159     }
160 
161     /**
162      * @see org.kuali.rice.krad.uif.element.ProgressBar#getSegmentPercentages()
163      */
164     public void setSegmentPercentages(List<String> segmentPercentages) {
165         // Note: This is purposely taking in a list of String to make bean configuration easier
166         if (this.segmentPercentages == null) {
167             this.segmentPercentages = new ArrayList<Integer>();
168         }
169 
170         for (String percentage : segmentPercentages) {
171             this.segmentPercentages.add(new Integer(percentage));
172         }
173     }
174 
175     /**
176      * The bar sizes as String css style properties (ie, "width: 20%") in a list, framework only,
177      * not settable.
178      *
179      * @return the bar sizes as String css style properties
180      */
181     public List<String> getSegmentSizes() {
182         return segmentSizes;
183     }
184 
185     /**
186      * True if this ProgressBar should render vertical (this requires a defined height - which by default is
187      * defined in the css, or by the framework for StepProgressBars), false otherwise
188      *
189      * @return true if this
190      */
191     @BeanTagAttribute(name = "vertical")
192     public boolean isVertical() {
193         return vertical;
194     }
195 
196     /**
197      * @see ProgressBar#isVertical()
198      */
199     public void setVertical(boolean vertical) {
200         this.vertical = vertical;
201     }
202 
203 }