KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > workplace > CmsWidgetDialogParameter


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/CmsWidgetDialogParameter.java,v $
3  * Date : $Date: 2006/03/27 14:52:43 $
4  * Version: $Revision: 1.13 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.workplace;
33
34 import org.opencms.file.CmsObject;
35 import org.opencms.main.CmsException;
36 import org.opencms.main.CmsIllegalArgumentException;
37 import org.opencms.main.CmsRuntimeException;
38 import org.opencms.util.CmsStringUtil;
39 import org.opencms.widgets.A_CmsWidget;
40 import org.opencms.widgets.CmsWidgetException;
41 import org.opencms.widgets.I_CmsWidget;
42 import org.opencms.widgets.I_CmsWidgetParameter;
43 import org.opencms.widgets.Messages;
44
45 import java.lang.reflect.InvocationTargetException JavaDoc;
46 import java.util.ArrayList JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.SortedMap JavaDoc;
49
50 import org.apache.commons.beanutils.ConvertUtilsBean;
51 import org.apache.commons.beanutils.PropertyUtilsBean;
52
53 /**
54  * Implements the widget parameter interface for the use of OpenCms widgets on dialogs that
55  * are not based on XML contents.<p>
56  *
57  * @author Alexander Kandzior
58  *
59  * @version $Revision: 1.13 $
60  *
61  * @since 6.0.0
62  */

63 public class CmsWidgetDialogParameter implements I_CmsWidgetParameter {
64
65     /** The name of the default dialog page. */
66     public static final String JavaDoc DEFAULT_DIALOG_PAGE = "default";
67
68     /** The maximum number of occurences of a widget dialog element in a list of elements. */
69     public static final int MAX_OCCURENCES = 200;
70
71     /** The (optional) base collection for read / writing collection based parameters. */
72     protected Object JavaDoc m_baseCollection;
73
74     /** The (optional) base object for read / writing the parameter value to. */
75     protected Object JavaDoc m_baseObject;
76
77     /** The (optinal) object property to read / write this parameter value to. */
78     protected String JavaDoc m_baseObjectProperty;
79
80     /** The default value of the parameter. */
81     protected String JavaDoc m_defaultValue;
82
83     /** The name of the dialog (page) the widget is used on. */
84     protected String JavaDoc m_dialogPage;
85
86     /** Indicates if the widget value has an error. */
87     protected Throwable JavaDoc m_error;
88
89     /** The id of the parameter on the form. */
90     protected String JavaDoc m_id;
91
92     /** The index of this parameter in the (optional) list of parameters. */
93     protected int m_index;
94
95     /** The maximum number of occurences of this parameter. */
96     protected int m_maxOccurs;
97
98     /** The minimum number of occurences of this parameter. */
99     protected int m_minOccurs;
100
101     /** The name of the parameter. */
102     protected String JavaDoc m_name;
103
104     /** Optional localized key prefix identificator. */
105     protected String JavaDoc m_prefix;
106
107     /** The value of the parameter. */
108     protected String JavaDoc m_value;
109
110     /** The widget used for the parameter. */
111     protected I_CmsWidget m_widget;
112
113     /**
114      * Create a new Widget parameter.<p>
115      *
116      * @param base the base of the parameter
117      * @param index the index of this parameter in the list
118      */

119     public CmsWidgetDialogParameter(CmsWidgetDialogParameter base, int index) {
120
121         this(
122             null,
123             base.m_defaultValue,
124             base.getName(),
125             base.getWidget(),
126             base.getDialogPage(),
127             base.getMinOccurs(),
128             base.getMaxOccurs(),
129             index);
130
131         m_baseObject = base.m_baseObject;
132         m_baseObjectProperty = base.m_baseObjectProperty;
133         m_baseCollection = base.m_baseCollection;
134         m_prefix = base.m_prefix;
135     }
136
137     /**
138      * Create a new Widget parameter.<p>
139      *
140      * @param base the base of the parameter
141      * @param index the index of this parameter in the list
142      * @param originalIndex the original index in the previous version of the list
143      */

144     public CmsWidgetDialogParameter(CmsWidgetDialogParameter base, int index, int originalIndex) {
145
146         this(
147             null,
148             base.m_defaultValue,
149             base.getName(),
150             base.getWidget(),
151             base.getDialogPage(),
152             base.getMinOccurs(),
153             base.getMaxOccurs(),
154             index);
155
156         m_baseObject = base.m_baseObject;
157         m_baseObjectProperty = base.m_baseObjectProperty;
158         m_baseCollection = base.m_baseCollection;
159
160         if (m_baseCollection != null) {
161             if (m_baseCollection instanceof List JavaDoc) {
162                 // base object is a list - make sure to set possible old value
163
List JavaDoc baseList = (List JavaDoc)m_baseCollection;
164                 if (originalIndex < baseList.size()) {
165                     Object JavaDoc o = baseList.get(originalIndex);
166                     if (o != null) {
167                         m_value = o.toString();
168                     }
169                 }
170             } else if (m_baseCollection instanceof SortedMap JavaDoc) {
171                 // base object is a sorted map - make sure to set possible old value
172
SortedMap JavaDoc baseMap = (SortedMap JavaDoc)m_baseCollection;
173                 List JavaDoc keyList = new ArrayList JavaDoc(baseMap.keySet());
174                 if (originalIndex < keyList.size()) {
175                     Object JavaDoc key = keyList.get(originalIndex);
176                     Object JavaDoc value = baseMap.get(key);
177                     StringBuffer JavaDoc val = new StringBuffer JavaDoc();
178                     val.append(key != null ? key.toString() : "");
179                     val.append('=');
180                     val.append(value != null ? value.toString() : "");
181                     m_value = val.toString();
182                 }
183             }
184         }
185     }
186
187     /**
188      * Create a new Widget parameter based on a given object's property.<p>
189      *
190      * @param base the base object to map the parameter to / from
191      * @param property the base object property to map the parameter to / from
192      * @param widget the widget used for this parameter
193      */

194     public CmsWidgetDialogParameter(Object JavaDoc base, String JavaDoc property, I_CmsWidget widget) {
195
196         this(base, property, DEFAULT_DIALOG_PAGE, widget);
197     }
198
199     /**
200      * Create a new Widget parameter based on a given object's property.<p>
201      *
202      * @param base the base object to map the parameter to / from
203      * @param property the base object property to map the parameter to / from
204      * @param dialogPage the dialog page to use the widget on
205      * @param widget the widget used for this parameter
206      */

207     public CmsWidgetDialogParameter(Object JavaDoc base, String JavaDoc property, String JavaDoc dialogPage, I_CmsWidget widget) {
208
209         this(base, property, null, dialogPage, widget, 1, 1);
210     }
211
212     /**
213      * Create a new Widget parameter based on a given object's property.<p>
214      *
215      * @param base the base object to map the parameter to / from
216      * @param property the base object property to map the parameter to / from
217      * @param htmlName the form id name to use in the generated HTML
218      * @param dialogPage the dialog page to use the widget on
219      * @param widget the widget used for this parameter
220      *
221      */

222     public CmsWidgetDialogParameter(Object JavaDoc base, String JavaDoc property, String JavaDoc htmlName, String JavaDoc dialogPage, I_CmsWidget widget) {
223
224         this(base, property, htmlName, null, dialogPage, widget, 1, 1);
225     }
226
227     /**
228      * Create a new Widget parameter based on a given object's property.<p>
229      *
230      * @param base the base object to map the parameter to / from
231      * @param property the base object property to map the parameter to / from
232      * @param defaultValue the default value to use for this parameter
233      * @param dialogPage the dialog page to use the widget on
234      * @param widget the widget used for this paramete
235      * @param minOccurs the required minimum numer of occurences of this parameter
236      * @param maxOccurs the maximum allowed numer of occurences of this parameter
237      */

238     public CmsWidgetDialogParameter(
239         Object JavaDoc base,
240         String JavaDoc property,
241         String JavaDoc defaultValue,
242         String JavaDoc dialogPage,
243         I_CmsWidget widget,
244         int minOccurs,
245         int maxOccurs) {
246
247         this(base, property, property, defaultValue, dialogPage, widget, minOccurs, maxOccurs);
248     }
249
250     /**
251      * Create a new Widget parameter based on a given object's property.<p>
252      *
253      * @param base the base object to map the parameter to / from
254      * @param property the base object property to map the parameter to / from
255      * @param htmlName the form id name to use in the generated HTML
256      * @param defaultValue the default value to use for this parameter
257      * @param dialogPage the dialog page to use the widget on
258      * @param widget the widget used for this paramete
259      * @param minOccurs the required minimum numer of occurences of this parameter
260      * @param maxOccurs the maximum allowed numer of occurences of this parameter
261      */

262     public CmsWidgetDialogParameter(
263         Object JavaDoc base,
264         String JavaDoc property,
265         String JavaDoc htmlName,
266         String JavaDoc defaultValue,
267         String JavaDoc dialogPage,
268         I_CmsWidget widget,
269         int minOccurs,
270         int maxOccurs) {
271
272         if (htmlName == null) {
273             htmlName = property;
274         }
275
276         if ((base instanceof List JavaDoc) || (base instanceof SortedMap JavaDoc)) {
277
278             // this is a list, use custom list mappings
279
init(null, defaultValue, htmlName, widget, dialogPage, 0, MAX_OCCURENCES, 0);
280
281             m_baseObject = null;
282             m_baseObjectProperty = null;
283             m_baseCollection = base;
284
285         } else {
286
287             // generic object:use reflection to map object properties
288
init(null, defaultValue, htmlName, widget, dialogPage, minOccurs, maxOccurs, 0);
289
290             m_baseObject = base;
291             m_baseObjectProperty = property;
292             m_baseCollection = null;
293
294             PropertyUtilsBean bean = new PropertyUtilsBean();
295
296             // make sure the base object has the requested property
297
if (!bean.isReadable(m_baseObject, m_baseObjectProperty)
298                 || !bean.isWriteable(m_baseObject, m_baseObjectProperty)) {
299
300                 throw new CmsIllegalArgumentException(Messages.get().container(
301                     Messages.ERR_NO_PROPERTY_2,
302                     base.getClass().getName(),
303                     property));
304             }
305
306             Object JavaDoc value;
307             try {
308                 value = bean.getNestedProperty(m_baseObject, m_baseObjectProperty);
309             } catch (Exception JavaDoc e) {
310                 throw new CmsRuntimeException(Messages.get().container(
311                     Messages.ERR_PROPERTY_READ_2,
312                     property,
313                     base.getClass().getName()), e);
314             }
315
316             if (value != null) {
317
318                 if ((value instanceof List JavaDoc) || (value instanceof SortedMap JavaDoc)) {
319                     m_baseCollection = value;
320                     m_minOccurs = 0;
321                     m_maxOccurs = MAX_OCCURENCES;
322                 } else {
323                     m_defaultValue = String.valueOf(value);
324                     m_value = m_defaultValue;
325                     if ((m_minOccurs == 0) && !m_value.equals(defaultValue)) {
326                         // if value is different from default ensure this widget is displayed
327
m_minOccurs = 1;
328                     }
329                 }
330             }
331         }
332     }
333
334     /**
335      * Create a new Widget parameter.<p>
336      *
337      * @param name the name of the parameter
338      * @param widget the widget used for this parameter
339      */

340     public CmsWidgetDialogParameter(String JavaDoc name, I_CmsWidget widget) {
341
342         this(null, null, name, widget, DEFAULT_DIALOG_PAGE, 1, 1, 0);
343     }
344
345     /**
346      * Create a new Widget parameter.<p>
347      *
348      * @param name the name of the parameter
349      * @param widget the widget used for this parameter
350      * @param minOccurs the required minimum numer of occurences of this parameter
351      * @param maxOccurs the maximum allowed numer of occurences of this parameter
352      */

353     public CmsWidgetDialogParameter(String JavaDoc name, I_CmsWidget widget, int minOccurs, int maxOccurs) {
354
355         this(null, null, name, widget, DEFAULT_DIALOG_PAGE, minOccurs, maxOccurs, 0);
356     }
357
358     /**
359      * Create a new Widget parameter with specified occurence settings.<p>
360      *
361      * @param value the initial value of the parameter
362      * @param defaultValue the default value of the parameter
363      * @param name the id of the parameter
364      * @param widget the widget used for this parameter
365      * @param dialog the dialog this parameter is used on
366      * @param minOccurs the required minimum numer of occurences of this parameter
367      * @param maxOccurs the maximum allowed numer of occurences of this parameter
368      * @param index the index of this parameter in the list
369      */

370     public CmsWidgetDialogParameter(
371         String JavaDoc value,
372         String JavaDoc defaultValue,
373         String JavaDoc name,
374         I_CmsWidget widget,
375         String JavaDoc dialog,
376         int minOccurs,
377         int maxOccurs,
378         int index) {
379
380         super();
381         init(value, defaultValue, name, widget, dialog, minOccurs, maxOccurs, index);
382     }
383
384     /**
385      * Returns a from id representation for the given widget name and id.<p>
386      *
387      * @param name the widget parameter name
388      * @param index the widget parameter index
389      *
390      * @return a from id representation for the given widget name and id
391      */

392     public static String JavaDoc createId(String JavaDoc name, int index) {
393
394         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
395         result.append(name);
396         result.append('.');
397         result.append(index);
398
399         return result.toString();
400     }
401
402     /**
403      * "Commits" (writes) the value of this widget back to the underlying base object.<p>
404      *
405      * @param dialog the widget dialog where the parameter is used on
406      *
407      * @throws CmsException in case the String value of the widget is invalid for the base Object
408      */

409     public void commitValue(CmsWidgetDialog dialog) throws CmsException {
410
411         if (m_baseCollection == null) {
412
413             PropertyUtilsBean bean = new PropertyUtilsBean();
414             ConvertUtilsBean converter = new ConvertUtilsBean();
415             Object JavaDoc value = null;
416             try {
417                 Class JavaDoc type = bean.getPropertyType(m_baseObject, m_baseObjectProperty);
418                 value = converter.convert(m_value, type);
419                 bean.setNestedProperty(m_baseObject, m_baseObjectProperty, value);
420                 setError(null);
421             } catch (InvocationTargetException JavaDoc e) {
422                 setError(e.getTargetException());
423                 throw new CmsWidgetException(Messages.get().container(
424                     Messages.ERR_PROPERTY_WRITE_3,
425                     value,
426                     dialog.keyDefault(A_CmsWidget.getLabelKey(this), getKey()),
427                     m_baseObject.getClass().getName()), e.getTargetException(), this);
428             } catch (Exception JavaDoc e) {
429                 setError(e);
430                 throw new CmsWidgetException(Messages.get().container(
431                     Messages.ERR_PROPERTY_WRITE_3,
432                     value,
433                     dialog.keyDefault(A_CmsWidget.getLabelKey(this), getKey()),
434                     m_baseObject.getClass().getName()), e, this);
435             }
436         } else if (m_baseCollection instanceof SortedMap JavaDoc) {
437             if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_value)) {
438                 int pos = m_value.indexOf('=');
439                 if ((pos > 0) && (pos < (m_value.length() - 1))) {
440                     String JavaDoc key = m_value.substring(0, pos);
441                     String JavaDoc value = m_value.substring(pos + 1);
442                     SortedMap JavaDoc map = (SortedMap JavaDoc)m_baseCollection;
443                     if (map.containsKey(key)) {
444                         Object JavaDoc val = map.get(key);
445                         CmsWidgetException error = new CmsWidgetException(Messages.get().container(
446                             Messages.ERR_MAP_DUPLICATE_KEY_3,
447                             dialog.keyDefault(A_CmsWidget.getLabelKey(this), getKey()),
448                             key,
449                             val), this);
450                         setError(error);
451                         throw error;
452                     }
453                     map.put(key, value);
454                 } else {
455                     CmsWidgetException error = new CmsWidgetException(Messages.get().container(
456                         Messages.ERR_MAP_PARAMETER_FORM_1,
457                         dialog.keyDefault(A_CmsWidget.getLabelKey(this), getKey())), this);
458                     setError(error);
459                     throw error;
460                 }
461             }
462         } else if (m_baseCollection instanceof List JavaDoc) {
463             if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_value)) {
464                 List JavaDoc list = (List JavaDoc)m_baseCollection;
465                 list.add(m_value);
466             }
467         }
468     }
469
470     /**
471      * @see org.opencms.widgets.I_CmsWidgetParameter#getDefault(org.opencms.file.CmsObject)
472      */

473     public String JavaDoc getDefault(CmsObject cms) {
474
475         return m_defaultValue;
476     }
477
478     /**
479      * Returns the name of the dialog (or dialog page) this widget parameter is used on.<p>
480      *
481      * This information can be used to create multi-page dialogs where the
482      * widgets are spread over several pages.<p>
483      *
484      * @return the name of the dialog (or dialog page) this widget parameter is used on
485      */

486     public String JavaDoc getDialogPage() {
487
488         return m_dialogPage;
489     }
490
491     /**
492      * Returns the Exception caused when this parameter value was commited, or <code>null</code>
493      * if error occured.<p>
494      *
495      * @return the Exception caused when this parameter value was commited
496      */

497     public Throwable JavaDoc getError() {
498
499         return m_error;
500     }
501
502     /**
503      * @see org.opencms.widgets.I_CmsWidgetParameter#getId()
504      */

505     public String JavaDoc getId() {
506
507         return m_id;
508     }
509
510     /**
511      * @see org.opencms.widgets.I_CmsWidgetParameter#getIndex()
512      */

513     public int getIndex() {
514
515         return m_index;
516     }
517
518     /**
519      * @see org.opencms.widgets.I_CmsWidgetParameter#getKey()
520      */

521     public String JavaDoc getKey() {
522
523         StringBuffer JavaDoc result = new StringBuffer JavaDoc(128);
524         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_prefix)) {
525             result.append(m_prefix);
526             result.append('.');
527         }
528         result.append(getName());
529         return result.toString();
530     }
531
532     /**
533      * @see org.opencms.widgets.I_CmsWidgetParameter#getMaxOccurs()
534      */

535     public int getMaxOccurs() {
536
537         return m_maxOccurs;
538     }
539
540     /**
541      * @see org.opencms.widgets.I_CmsWidgetParameter#getMinOccurs()
542      */

543     public int getMinOccurs() {
544
545         return m_minOccurs;
546     }
547
548     /**
549      * @see org.opencms.widgets.I_CmsWidgetParameter#getName()
550      */

551     public String JavaDoc getName() {
552
553         return m_name;
554     }
555
556     /**
557      * @see org.opencms.widgets.I_CmsWidgetParameter#getStringValue(org.opencms.file.CmsObject)
558      */

559     public String JavaDoc getStringValue(CmsObject cms) throws CmsRuntimeException {
560
561         return m_value;
562     }
563
564     /**
565      * Returns the widget for this parameter.<p>
566      *
567      * @return the widget for this parameter
568      */

569     public I_CmsWidget getWidget() {
570
571         return m_widget;
572     }
573
574     /**
575      * @see org.opencms.widgets.I_CmsWidgetParameter#hasError()
576      */

577     public boolean hasError() {
578
579         return m_error != null;
580     }
581
582     /**
583      * Checks if a value for this widget base type with the given id is available.<p>
584      *
585      * This should only be used if the base object is a collection.<p>
586      *
587      * @param index the index to check
588      *
589      * @return <code>true</code> if a value for this widget base type with the given id is available
590      */

591     public boolean hasValue(int index) {
592
593         if (m_baseCollection instanceof List JavaDoc) {
594             return index < ((List JavaDoc)m_baseCollection).size();
595         } else if (m_baseCollection instanceof SortedMap JavaDoc) {
596             return index < ((SortedMap JavaDoc)m_baseCollection).size();
597         }
598         return false;
599     }
600
601     /**
602      * Returns <code>true</code> if this widget parameter is mapped to a Collection base object.<p>
603      *
604      * @return <code>true</code> if this widget parameter is mapped to a Collection base object
605      */

606     public boolean isCollectionBase() {
607
608         return (m_baseCollection != null)
609             && ((m_baseCollection instanceof List JavaDoc) || (m_baseCollection instanceof SortedMap JavaDoc));
610     }
611
612     /**
613      * Prepares this widget dialog parameter to be commited.<p>
614      *
615      * This is required if the base type is mapped to a Collection object,
616      * becasue the collection needs to be cleared before the new values are set.<p>
617      */

618     public void prepareCommit() {
619
620         if (m_baseCollection instanceof List JavaDoc) {
621             List JavaDoc list = (List JavaDoc)m_baseCollection;
622             list.clear();
623         } else if (m_baseCollection instanceof SortedMap JavaDoc) {
624             SortedMap JavaDoc map = (SortedMap JavaDoc)m_baseCollection;
625             map.clear();
626         }
627     }
628
629     /**
630      * Sets the error state of this widget.<p>
631      *
632      * If the argument is <code>null</code> then the state is set to "no error".<p>
633      *
634      * @param error the error state to set
635      */

636     public void setError(Throwable JavaDoc error) {
637
638         m_error = error;
639     }
640
641     /**
642      * Sets the index to the provided value.<p>
643      *
644      * @param index the new index value to set
645      */

646     public void setindex(int index) {
647
648         m_index = index;
649         m_id = createId(m_name, m_index);
650     }
651
652     /**
653      * @see org.opencms.widgets.I_CmsWidgetParameter#setKeyPrefix(java.lang.String)
654      */

655     public void setKeyPrefix(String JavaDoc prefix) {
656
657         m_prefix = prefix;
658     }
659
660     /**
661      * @see org.opencms.widgets.I_CmsWidgetParameter#setStringValue(org.opencms.file.CmsObject, java.lang.String)
662      */

663     public void setStringValue(CmsObject cms, String JavaDoc value) throws CmsIllegalArgumentException {
664
665         m_value = value;
666     }
667
668     /**
669      * Initializes a widget parameter with the given values.<p>
670      *
671      * @param value the initial value of the parameter
672      * @param defaultValue the default value of the parameter
673      * @param name the id of the parameter
674      * @param widget the widget used for this parameter
675      * @param dialog the dialog this parameter is used on
676      * @param minOccurs the required minimum numer of occurences of this parameter
677      * @param maxOccurs the maximum allowed numer of occurences of this parameter
678      * @param index the index of this parameter in the list
679      */

680     protected void init(
681         String JavaDoc value,
682         String JavaDoc defaultValue,
683         String JavaDoc name,
684         I_CmsWidget widget,
685         String JavaDoc dialog,
686         int minOccurs,
687         int maxOccurs,
688         int index) {
689
690         if (defaultValue == null) {
691             m_defaultValue = "";
692         } else {
693             m_defaultValue = defaultValue;
694         }
695         if (value == null) {
696             m_value = m_defaultValue;
697         } else {
698             m_value = value;
699         }
700         m_name = name;
701         m_widget = widget;
702         if (maxOccurs < MAX_OCCURENCES) {
703             m_maxOccurs = maxOccurs;
704         } else {
705             m_maxOccurs = MAX_OCCURENCES;
706         }
707         if (minOccurs >= 0) {
708             m_minOccurs = minOccurs;
709         } else {
710             m_minOccurs = 0;
711         }
712         if (m_minOccurs > m_maxOccurs) {
713             m_minOccurs = m_maxOccurs;
714         }
715         m_dialogPage = dialog;
716         m_error = null;
717
718         setindex(index);
719     }
720 }
Popular Tags