View Javadoc

1   /**
2    * This file Copyright (c) 2003-2011 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.gui.dialog;
35  
36  import info.magnolia.cms.beans.config.ContentRepository;
37  import info.magnolia.cms.core.Content;
38  import info.magnolia.cms.gui.control.Button;
39  import info.magnolia.cms.gui.control.ButtonSet;
40  import info.magnolia.cms.gui.control.ControlImpl;
41  import info.magnolia.cms.gui.control.Hidden;
42  import info.magnolia.cms.gui.misc.CssConstants;
43  import info.magnolia.cms.security.AccessDeniedException;
44  import info.magnolia.cms.util.ContentUtil;
45  import info.magnolia.cms.util.NodeDataUtil;
46  
47  import java.io.IOException;
48  import java.io.Writer;
49  import java.util.ArrayList;
50  import java.util.Collection;
51  import java.util.Iterator;
52  import java.util.List;
53  
54  import javax.jcr.PathNotFoundException;
55  import javax.jcr.PropertyType;
56  import javax.jcr.RepositoryException;
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpServletResponse;
59  
60  import org.apache.commons.lang.StringUtils;
61  import org.slf4j.Logger;
62  import org.slf4j.LoggerFactory;
63  
64  
65  /**
66   * @author Vinzenz Wyser
67   * @version 2.0
68   */
69  public class DialogButtonSet extends DialogBox {
70  
71      /**
72       * Logger.
73       */
74      private static Logger log = LoggerFactory.getLogger(DialogButtonSet.class);
75  
76      private int buttonType = ControlImpl.BUTTONTYPE_RADIO;
77  
78      public void setOptions(Content configNode, boolean setDefaultSelected) {
79          // setDefaultSelected: does not work properly (no difference between never stored and removed...)
80          // therefore do only use for radio, not for checkbox
81          List options = new ArrayList();
82          try {
83              Iterator it = getOptionNodes(configNode).iterator();
84              while (it.hasNext()) {
85                  Content n = ((Content) it.next());
86                  String valueNodeData = this.getConfigValue("valueNodeData", "value");
87                  String labelNodeData = this.getConfigValue("labelNodeData", "label");
88  
89                  String value = NodeDataUtil.getString(n, valueNodeData);//$NON-NLS-1$
90                  String label = NodeDataUtil.getString(n, labelNodeData);//$NON-NLS-1$
91  
92                  //label = this.getMessage(label);
93                  Button button = new Button(this.getName(), value);
94                  // if (n.getNodeData("label").isExist()) button.setLabel(n.getNodeData("label").getString());
95                  button.setLabel(label);
96  
97                  String iconSrc = n.getNodeData("iconSrc").getString(); //$NON-NLS-1$
98                  if (StringUtils.isNotEmpty(iconSrc)) {
99                      button.setIconSrc(iconSrc);
100                 }
101 
102                 if (setDefaultSelected && n.getNodeData("selected").getBoolean()) { //$NON-NLS-1$
103                     button.setState(ControlImpl.BUTTONSTATE_PUSHED);
104                 }
105                 options.add(button);
106             }
107         }
108         catch (RepositoryException e) {
109             if (log.isDebugEnabled()) {
110                 log.debug("Exception caught: " + e.getMessage(), e); //$NON-NLS-1$
111             }
112         }
113         this.setOptions(options);
114     }
115 
116     protected Collection getOptionNodes(Content configNode) throws PathNotFoundException, RepositoryException, AccessDeniedException {
117         Content optionsNode = null;
118 
119         if(configNode.hasContent("options")){
120             optionsNode = configNode.getContent("options"); //$NON-NLS-1$
121         }
122         else{
123             String repository = this.getConfigValue("repository", ContentRepository.WEBSITE);
124             String path = this.getConfigValue("path");
125             if(StringUtils.isNotEmpty(path)){
126                 optionsNode = ContentUtil.getContent(repository, path);
127             }
128         }
129 
130         if(optionsNode != null){
131             return ContentUtil.getAllChildren(optionsNode);
132         }
133         return new ArrayList();
134     }
135 
136     public void setOption(Content configNode) {
137         // checkboxSwitch -> only one option, value always true/false
138         List options = new ArrayList();
139         Button button = new Button(this.getName() + "_dummy", StringUtils.EMPTY);
140         String label = configNode.getNodeData("buttonLabel").getString();
141         //label = this.getMessage(label);
142         button.setLabel(label);
143 
144         if (configNode.getNodeData("selected").getBoolean()) { //$NON-NLS-1$
145             button.setState(ControlImpl.BUTTONSTATE_PUSHED);
146         }
147 
148         button.setValue("true"); //$NON-NLS-1$
149         button.setOnclick("mgnlDialogShiftCheckboxSwitch('" + this.getName() + "');"); //$NON-NLS-1$ //$NON-NLS-2$
150         options.add(button);
151         this.setOptions(options);
152     }
153 
154     /**
155      * @see info.magnolia.cms.gui.dialog.DialogControl#init(HttpServletRequest, HttpServletResponse, Content, Content)
156      */
157     public void init(HttpServletRequest request, HttpServletResponse response, Content websiteNode, Content configNode)
158         throws RepositoryException {
159         super.init(request, response, websiteNode, configNode);
160 
161         // confignode can be null if instantiated directly
162         if (configNode != null) {
163             String controlType = this.getConfigValue("selectType",this.getConfigValue("controlType")); //$NON-NLS-1$
164 
165             if (log.isDebugEnabled()) {
166                 log.debug("Init DialogButtonSet with type=" + controlType); //$NON-NLS-1$
167             }
168 
169             // custom settings
170             if (controlType.equals("radio")) { //$NON-NLS-1$
171                 setButtonType(ControlImpl.BUTTONTYPE_RADIO);
172                 setOptions(configNode, true);
173             }
174             else if (controlType.equals("checkbox")) { //$NON-NLS-1$
175                 setButtonType(ControlImpl.BUTTONTYPE_CHECKBOX);
176                 setOptions(configNode, false);
177                 setConfig("valueType", "multiple"); //$NON-NLS-1$ //$NON-NLS-2$
178             }
179             else if (controlType.equals("checkboxSwitch")) { //$NON-NLS-1$
180                 setButtonType(ControlImpl.BUTTONTYPE_CHECKBOX);
181                 setOption(configNode);
182             }
183         }
184     }
185 
186     public void drawHtmlPreSubs(Writer out) throws IOException {
187         this.drawHtmlPre(out);
188     }
189 
190     public void drawHtmlPostSubs(Writer out) throws IOException {
191         this.drawHtmlPost(out);
192     }
193 
194     public void setButtonType(int i) {
195         this.buttonType = i;
196     }
197 
198     public int getButtonType() {
199         return this.buttonType;
200     }
201 
202     /**
203      * @see info.magnolia.cms.gui.dialog.DialogControl#drawHtml(Writer)
204      */
205     public void drawHtml(Writer out) throws IOException {
206         this.drawHtmlPre(out);
207         
208         for (int i = 0; i < this.getOptions().size(); i++) {
209             Button b = (Button) this.getOptions().get(i);
210          // translate
211             b.setLabel(this.getMessage(b.getLabel()));
212             if(b.getName().endsWith("_dummy")){
213                 b.setName(this.getName() + "_dummy");
214                 b.setOnclick("mgnlDialogShiftCheckboxSwitch('" + this.getName() + "');");
215             }else if(this.getName().startsWith(b.getName() + "_")){
216                 b.setName(this.getName());
217             }
218         }
219 
220         ButtonSet control;
221         if (this.getConfigValue("valueType").equals("multiple")) { //$NON-NLS-1$ //$NON-NLS-2$
222             // checkbox
223             control = new ButtonSet(this.getName(), this.getValues());
224             control.setValueType(ControlImpl.VALUETYPE_MULTIPLE);
225         }
226         else if (this.getButtonType() == ControlImpl.BUTTONTYPE_CHECKBOX) {
227             // checkboxSwitch
228             control = new ButtonSet(this.getName() + "_SWITCH", this.getValue()); //$NON-NLS-1$
229         }
230         else {
231             // radio
232             control = new ButtonSet(this.getName(), this.getValue());
233         }
234         control.setButtonType(this.getButtonType());
235 
236         // maem: extension to allow for fine grained layout control. E.g. radio buttons with picture
237         control.setCssClass(this.getConfigValue("cssClass", CssConstants.CSSCLASS_BUTTONSETBUTTON)); //$NON-NLS-1$
238 
239         if (this.getConfigValue("saveInfo").equals("false")) { //$NON-NLS-1$ //$NON-NLS-2$
240             control.setSaveInfo(false);
241         }
242         final String type = this.getConfigValue("type", PropertyType.TYPENAME_STRING);
243         control.setType(type); //$NON-NLS-1$
244         String width = this.getConfigValue("width", null); //$NON-NLS-1$
245         control.setButtonHtmlPre("<tr><td class=\"" + CssConstants.CSSCLASS_BUTTONSETBUTTON + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
246         control.setButtonHtmlInter("</td><td class=\"" + CssConstants.CSSCLASS_BUTTONSETLABEL + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
247         control.setButtonHtmlPost("</td></tr>"); //$NON-NLS-1$
248         int cols = Integer.valueOf(this.getConfigValue("cols", "1")).intValue(); //$NON-NLS-1$ //$NON-NLS-2$
249         if (cols > 1) {
250             width = "100%"; // outer table squeezes inner table if outer's width is not defined... //$NON-NLS-1$
251             control.setHtmlPre(control.getHtmlPre() + "<tr>"); //$NON-NLS-1$
252             control.setHtmlPost("</tr>" + control.getHtmlPost()); //$NON-NLS-1$
253             int item = 1;
254             int itemsPerCol = (int) Math.ceil(this.getOptions().size() / ((double) cols));
255             for (int i = 0; i < this.getOptions().size(); i++) {
256                 Button b = (Button) this.getOptions().get(i);
257                 if (item == 1) {
258                     b.setHtmlPre("<td><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" //$NON-NLS-1$
259                         + control.getButtonHtmlPre());
260                 }
261                 if (item == itemsPerCol) {
262                     b.setHtmlPost(control.getButtonHtmlPost() + "</table></td><td class=\"" //$NON-NLS-1$
263                         + CssConstants.CSSCLASS_BUTTONSETINTERCOL
264                         + "\"></td>"); //$NON-NLS-1$
265                     item = 1;
266                 }
267                 else {
268                     item++;
269                 }
270             }
271             // very last button: close table
272             int lastIndex = this.getOptions().size() - 1;
273             // avoid ArrayIndexOutOfBoundsException, but should not happen
274             if (lastIndex > -1) {
275                 ((Button) this.getOptions().get(lastIndex)).setHtmlPost(control.getButtonHtmlPost() + "</table>"); //$NON-NLS-1$
276             }
277         }
278         if (width != null) {
279             control.setHtmlPre("<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"" + width + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
280         }
281         control.setButtons(this.getOptions());
282         out.write(control.getHtml());
283         if (control.getButtonType() == ControlImpl.BUTTONTYPE_CHECKBOX
284             && control.getValueType() != ControlImpl.VALUETYPE_MULTIPLE) {
285             // checkboxSwitch: value is stored in a hidden field (allows default selecting)
286             String value = this.getValue();
287             if (StringUtils.isEmpty(value)) {
288                 if (this.getConfigValue("selected").equals("true")) { //$NON-NLS-1$ //$NON-NLS-2$
289                     value = "true"; //$NON-NLS-1$
290                 }
291                 else {
292                     value = "false"; //$NON-NLS-1$
293                 }
294             }
295             Hidden hiddenValueField = new Hidden(this.getName(), value);
296             hiddenValueField.setType(type);
297 
298             out.write(hiddenValueField.getHtml());
299         }
300         this.drawHtmlPost(out);
301     }
302 }