Source Code Cross Referenced for EditableList.java in  » IDE-Netbeans » visualweb.api.designer » com » sun » rave » web » ui » component » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » visualweb.api.designer » com.sun.rave.web.ui.component 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        package com.sun.rave.web.ui.component;
0042:
0043:        import java.lang.reflect.Array;
0044:        import java.io.Serializable;
0045:        import java.text.Collator;
0046:        import java.text.MessageFormat;
0047:        import java.util.ArrayList;
0048:        import java.util.Comparator;
0049:        import java.util.Iterator;
0050:        import java.util.Locale;
0051:        import java.util.Properties;
0052:        import java.util.TreeMap;
0053:        import javax.faces.FacesException;
0054:        import javax.faces.application.FacesMessage;
0055:        import javax.faces.component.EditableValueHolder;
0056:        import javax.faces.component.UIComponent;
0057:        import javax.faces.component.ValueHolder;
0058:        import javax.faces.context.FacesContext;
0059:        import javax.faces.convert.ConverterException;
0060:        import javax.faces.el.EvaluationException;
0061:        import javax.faces.el.MethodBinding;
0062:        import javax.faces.el.MethodNotFoundException;
0063:        import javax.faces.el.ValueBinding;
0064:        import javax.faces.event.AbortProcessingException;
0065:        import javax.faces.event.ActionEvent;
0066:        import javax.faces.event.ActionListener; //import javax.faces.validator.ValidatorException;
0067:        import com.sun.rave.web.ui.component.Button;
0068:        import com.sun.rave.web.ui.component.TextField;
0069:        import com.sun.rave.web.ui.component.Label;
0070:        import com.sun.rave.web.ui.component.StaticText;
0071:        import com.sun.rave.web.ui.model.list.ListItem;
0072:        import com.sun.rave.web.ui.theme.Theme;
0073:        import com.sun.rave.web.ui.util.MessageUtil;
0074:        import com.sun.rave.web.ui.util.ThemeUtilities;
0075:        import com.sun.rave.web.ui.util.ConversionUtilities;
0076:        import com.sun.rave.web.ui.validator.StringLengthValidator;
0077:
0078:        /**
0079:         * <h4>About this tag.</h4>
0080:         *
0081:         *    <p>This tag renders an EditableList component. Use this component
0082:         *    when web application users need to create and modify a list of
0083:         *    strings. The application user can add new strings by typing them
0084:         *    into the textfield and clicking the "Add" button, and remove them
0085:         *    by selecting one or more items from the list and clicking the
0086:         *    "Remove" button.</p>
0087:         *
0088:         *    <h4>Configuring the listbox tag</h4>
0089:         *
0090:         *    <p> Use the <code>list</code> attribute to bind the component
0091:         *    to a model. The value must be an EL expression that corresponds to
0092:         *    a managed bean or a property of a managed bean, and it must
0093:         *    evaluate to an array of  <code>java.lang.String</code>.
0094:         *    </p>
0095:         *
0096:         *    <p>To set the label of the textfield, use the
0097:         *    <code>fieldLabel</code> attribute. To set the label of the
0098:         *    textfield, use the <code>listLabel</code> attribute. To validate
0099:         *    new items, use the <code>fieldValidator</code> attribute; to
0100:         *    validate the contents of the list once the user has finished
0101:         *    adding and removing items, specify a <code>labelValidator</code>.</p>
0102:         *
0103:         *    <h4>Facets</h4>
0104:         *
0105:         *    <ul>
0106:         *    <li><code>fieldLabel</code>: use this facet to specify a custom
0107:         *    component for the textfield label.</li>
0108:         *    <li><code>listLabel</code>: use this facet to specify a custom
0109:         *    component for the textfield label.</li>
0110:         *    <li><code>field</code>: use this facet to specify a custom
0111:         *    component for the textfield.</li>
0112:         *     <li><code>addButton</code>: use this facet to specify a custom
0113:         *    component for the add button.</li>
0114:         *     <li><code>removeButton</code>: use this facet to specify a custom
0115:         *    component for the remove button.</li>
0116:         *    <li><code>search</code>: use this facet to specify a custom
0117:         *    component for the search button. </li>
0118:         *    <li><code>readOnly</code>: use this facet to specify a custom
0119:         *    component for display a readonly version of the component.</li>
0120:         *    <li><code>header</code>: use this facet to specify a header,
0121:         *    rendered in a table row above the component.</li>
0122:         *    <li><code>footer</code>: use this facet to specify a header,
0123:         *    rendered in a table row below the component.</li>
0124:         *    </ul>
0125:         *
0126:         *    <h4>Client-side JavaScript functions</h4>
0127:         *
0128:         *    <ul>
0129:         *    <li>NONE yet</li>
0130:         *    </ul>
0131:         * @author avk
0132:         */
0133:        public class EditableList extends EditableListBase implements 
0134:                ListManager {
0135:
0136:            /**
0137:             * The component id for the ADD button
0138:             */
0139:            public static final String ADD_BUTTON_ID = "_addButton"; //NOI18N
0140:            public static final String ADD_BUTTON_FACET = "addButton"; //NOI18N
0141:            /**
0142:             * The component ID for the remove button
0143:             */
0144:            public static final String REMOVE_BUTTON_ID = "_removeButton"; //NOI18N
0145:            public static final String REMOVE_BUTTON_FACET = "removeButton"; //NOI18N
0146:            /**
0147:             * The component ID for the textfield
0148:             */
0149:            public static final String FIELD_ID = "_field"; //NOI18N
0150:            public static final String FIELD_FACET = "field"; //NOI18N
0151:
0152:            /**
0153:             * The component ID for the textfield
0154:             */
0155:            public static final String LIST_LABEL_ID = "_listLabel"; //NOI18N
0156:            public static final String LIST_LABEL_FACET = "listLabel"; //NOI18N
0157:
0158:            /**
0159:             * The component ID for the textfield
0160:             */
0161:            public static final String FIELD_LABEL_ID = "_fieldLabel"; //NOI18N
0162:            public static final String FIELD_LABEL_FACET = "fieldLabel"; //NOI18N
0163:
0164:            /**
0165:             * The component ID for the textfield
0166:             */
0167:            public static final String READ_ONLY_ID = "_readOnly"; //NOI18N
0168:            public static final String READ_ONLY_FACET = "readOnly"; //NOI18N
0169:
0170:            /**
0171:             * Facet name for the header facet
0172:             */
0173:            public static final String HEADER_FACET = "header"; //NOI18N
0174:
0175:            /**
0176:             * Facet name for the footer facet
0177:             */
0178:            public static final String FOOTER_FACET = "footer"; //NOI18N
0179:
0180:            /**
0181:             * The name of the component attribute that stores the name of the JavaScript object that organizes the JavsSCript functions for the component
0182:             */
0183:            public static final String JSOBJECT = "com.sun.rave.web.ui.EditabelListJS";
0184:
0185:            /**
0186:             * Name of the JavaScript function which is responsible for adding elements from the availble list to the selected list
0187:             */
0188:            public static final String ADD_FUNCTION = ".add(); ";
0189:
0190:            /**
0191:             * Name of the JavaScript function which is responsible for
0192:             * enabling/disabling the add button
0193:             */
0194:            public static final String ENABLE_ADD_FUNCTION = ".enableAdd(); ";
0195:
0196:            /**
0197:             * Name of the JavaScript function which is responsible for
0198:             * enabling/disabling the add button
0199:             */
0200:            public static final String SET_ADD_DISABLED_FUNCTION = ".setAddDisabled(false);";
0201:
0202:            /**
0203:             * Name of the JavaScript function which is responsible for
0204:             * enabling/disabling the remove button
0205:             */
0206:            public static final String ENABLE_REMOVE_FUNCTION = ".enableRemove(); ";
0207:
0208:            /**
0209:             * Name of the JavaScript function that updates the buttons
0210:             */
0211:            public static final String UPDATE_BUTTONS_FUNCTION = ".updateButtons(); ";
0212:            /**
0213:             *
0214:             * /**
0215:             * Read only separator string
0216:             */
0217:            private static final String READ_ONLY_SEPARATOR = ", "; //NOI18N
0218:
0219:            /**
0220:             * Facet name for the search facet
0221:             */
0222:            public static final String SEARCH_FACET = "search"; //NOI18N
0223:            public static final String SPACER_STRING = "_"; //NOI18N
0224:
0225:            private static final int MIN_LENGTH = 20;
0226:
0227:            private static final boolean DEBUG = false;
0228:
0229:            private TreeMap listItems = null;
0230:            private Collator collator = null;
0231:            private transient Theme theme = null;
0232:            private String selectedValue = null;
0233:            private String[] valuesToRemove = null;
0234:
0235:            /**
0236:             * Get the maximum length of the strings on the list
0237:             * @return An integer value for the maximum number of characters on the list
0238:             */
0239:            public int getMaxlLength() {
0240:                int length = super .getMaxLength();
0241:                if (length < 1) {
0242:                    length = 25;
0243:                    super .setMaxLength(length);
0244:                }
0245:                return length;
0246:            }
0247:
0248:            // Buttons
0249:            /**
0250:             * Get or create the ADD button. Retrieves the component specified by the
0251:             * addButton facet (if there is one) or creates a new Button component.
0252:             * @return A UI Component for the Add button
0253:             */
0254:            public UIComponent getAddButtonComponent() {
0255:
0256:                if (DEBUG)
0257:                    log("getAddButtonComponent()");
0258:
0259:                String id = getId();
0260:
0261:                // Check if the page author has defined an addbutton facet
0262:                UIComponent buttonComponent = getFacet(ADD_BUTTON_FACET);
0263:                // If the page author has not defined a button facet,
0264:                // check if the page author specified a button.
0265:                if (buttonComponent == null) {
0266:
0267:                    buttonComponent = createButton(getTheme().getMessage(
0268:                            "EditableList.add"), //NOI18N
0269:                            ADD_BUTTON_ID, ADD_BUTTON_FACET, new AddListener());
0270:                    ((Button) buttonComponent).setPrimary(true);
0271:                } else if (DEBUG) {
0272:                    log("\tFound facet."); //NOI18N
0273:                }
0274:                if (buttonComponent != null && isDisabled()) {
0275:                    buttonComponent.getAttributes().put("disabled",
0276:                            Boolean.TRUE); //NOI18N
0277:                }
0278:                return buttonComponent;
0279:            }
0280:
0281:            /**
0282:             * Get or create the REMOVE button. Retrieves the component specified by the
0283:             * removeButton facet (if there is one) or creates a new Button component.
0284:             * @return A UI Component for the REMOVE button
0285:             */
0286:            public UIComponent getRemoveButtonComponent() {
0287:
0288:                if (DEBUG)
0289:                    log("getRemoveButtonComponent()");
0290:
0291:                String id = getId();
0292:
0293:                // Check if the page author has defined an addbutton facet
0294:                UIComponent buttonComponent = getFacet(REMOVE_BUTTON_FACET);
0295:
0296:                // If the page author has not defined a button facet,
0297:                // check if the page author specified a button.
0298:                if (buttonComponent == null) {
0299:
0300:                    buttonComponent = createButton(
0301:                            getTheme().getMessage("EditableList.remove"), //NOI18N
0302:                            REMOVE_BUTTON_ID, REMOVE_BUTTON_FACET,
0303:                            new RemoveListener());
0304:                } else if (DEBUG) {
0305:                    log("\tFound facet."); //NOI18N
0306:                }
0307:
0308:                if (buttonComponent != null && isDisabled()) {
0309:                    buttonComponent.getAttributes().put("disabled",
0310:                            Boolean.TRUE); //NOI18N
0311:                }
0312:
0313:                return buttonComponent;
0314:
0315:            }
0316:
0317:            // Labels
0318:            /**
0319:             * Gets or creates a component for the list label. Retrieves the
0320:             * listLabel facet if one was specified, or creates a new label component.
0321:             * @return A UIComponent for the list label
0322:             */
0323:            public UIComponent getListLabelComponent() {
0324:
0325:                if (DEBUG)
0326:                    log("getListLabelComponent()");
0327:
0328:                String id = getId();
0329:
0330:                // Check if the page author has defined a label facet
0331:                UIComponent labelComponent = getFacet(LIST_LABEL_FACET);
0332:
0333:                // If the page author has not defined a label facet,
0334:                // check if the page author specified a label.
0335:                if (labelComponent == null) {
0336:
0337:                    String labelString = getListLabel();
0338:                    if (labelString == null || labelString.length() == 0) {
0339:                        labelString = getTheme().getMessage(
0340:                                "EditableList.defaultListLabel"); //NOI18N
0341:                    }
0342:
0343:                    labelComponent = createLabel(labelString, LIST_LABEL_ID,
0344:                            LIST_LABEL_FACET);
0345:
0346:                    ((Label) labelComponent).setLabeledComponent(this );
0347:                } else if (DEBUG) {
0348:                    log("\tFound facet."); //NOI18N
0349:                }
0350:
0351:                return labelComponent;
0352:            }
0353:
0354:            /**
0355:             * Gets or creates a component for the textfield label. Retrieves the
0356:             * fieldLabel facet if one was specified, or creates a new label component.
0357:             * @return A UIComponent for the field label
0358:             */
0359:            public UIComponent getFieldLabelComponent() {
0360:
0361:                if (DEBUG)
0362:                    log("getFieldLabelComponent()");
0363:
0364:                String id = getId();
0365:
0366:                // Check if the page author has defined a label facet
0367:                UIComponent labelComponent = getFacet(FIELD_LABEL_FACET);
0368:                // If the page author has not defined a label facet,
0369:                // check if the page author specified a label.
0370:                if (labelComponent == null) {
0371:
0372:                    String labelString = getFieldLabel();
0373:                    if (labelString == null || labelString.length() == 0) {
0374:                        labelString = getTheme().getMessage(
0375:                                "EditableList.defaultFieldLabel"); //NOI18N
0376:                    }
0377:
0378:                    labelComponent = createLabel(labelString, FIELD_LABEL_ID,
0379:                            FIELD_LABEL_FACET);
0380:
0381:                    ((Label) labelComponent)
0382:                            .setLabeledComponent(getFieldComponent());
0383:                } else if (DEBUG) {
0384:                    log("\tFound facet.");//NOI18N
0385:                }
0386:
0387:                return labelComponent;
0388:            }
0389:
0390:            // Other
0391:            /**
0392:             * Gets or creates a component for the textfield. Retrieves the
0393:             * field facet if one was specified, or creates a new TextField component.
0394:             * @return A UIComponent for the textfield
0395:             */
0396:            public UIComponent getFieldComponent() {
0397:
0398:                if (DEBUG)
0399:                    log("getFieldComponent()");
0400:
0401:                String id = getId();
0402:
0403:                // Check if the page author has defined a label facet
0404:                UIComponent fieldComponent = getFacet(FIELD_FACET);
0405:
0406:                // If the page author has not defined a field facet,
0407:                // check if the page author specified a field.
0408:                if (fieldComponent == null) {
0409:
0410:                    fieldComponent = createField(FIELD_ID, FIELD_FACET);
0411:                } else if (DEBUG) {
0412:                    log("\tFound facet.");//NOI18N
0413:                }
0414:
0415:                if (fieldComponent != null && isDisabled()) {
0416:                    fieldComponent.getAttributes()
0417:                            .put("disabled", Boolean.TRUE);//NOI18N
0418:                }
0419:                return fieldComponent;
0420:
0421:            }
0422:
0423:            // Readonly value
0424:            /**
0425:             * Return a string suitable for displaying the value in read only mode.
0426:             * The default is to separate the list values with a comma.
0427:             *
0428:             * @param context The FacesContext
0429:             * @throws javax.faces.FacesException If the list items cannot be processed
0430:             */
0431:            protected String getValueAsReadOnly(FacesContext context)
0432:                    throws FacesException {
0433:
0434:                // The comma format READ_ONLY_SEPARATOR should be part of the theme
0435:                // and/or configurable by the application
0436:                //
0437:                StringBuffer valueBuffer = new StringBuffer(200);
0438:
0439:                Iterator iterator = getListItems(context, false);
0440:
0441:                while (iterator.hasNext()) {
0442:                    String string = ((ListItem) (iterator.next())).getLabel();
0443:                    // Do this with a boolean on getListItems instead
0444:                    if (string.indexOf("nbsp") > -1) { //NOI18N
0445:                        continue;
0446:                    }
0447:                    valueBuffer.append(string);
0448:                    if (iterator.hasNext()) {
0449:                        valueBuffer.append(READ_ONLY_SEPARATOR);
0450:                    }
0451:                }
0452:                return valueBuffer.toString();
0453:            }
0454:
0455:            /**
0456:             * Creates a component for the EditableList in case the component
0457:             * is read-only.
0458:             * @return A UIComponent that displays the read-only value
0459:             */
0460:            public UIComponent getReadOnlyValueComponent() {
0461:
0462:                if (DEBUG)
0463:                    log("getReadOnlyValueComponent()");
0464:
0465:                String id = getId();
0466:
0467:                // Check if the page author has defined a label facet
0468:                UIComponent textComponent = getFacet(READ_ONLY_FACET); //NOI18N
0469:
0470:                // If the page author has not defined a label facet,
0471:                // check if the page author specified a label.
0472:                if (textComponent == null) {
0473:                    FacesContext context = FacesContext.getCurrentInstance();
0474:                    textComponent = createText(getValueAsReadOnly(context), //NOI18N
0475:                            READ_ONLY_ID, READ_ONLY_FACET);
0476:                } else if (DEBUG) {
0477:                    log("\tFound facet."); //NOI18N
0478:                }
0479:                return textComponent;
0480:            }
0481:
0482:            // The following methods overrides default behaviour that does not
0483:            // make sense for this component
0484:            /**
0485:             *
0486:             * @param converter
0487:             */
0488:            public void setConverter(javax.faces.convert.Converter converter) {
0489:                String msg = getTheme().getMessage("EditableList.noConversion"); //NOI18N
0490:                throw new RuntimeException(msg);
0491:            }
0492:
0493:            public String getJavaScriptObjectName() {
0494:                Object o = this .getAttributes().get(JSOBJECT);
0495:                String name = null;
0496:                if (o != null && o instanceof  String) {
0497:                    name = (String) o;
0498:                } else {
0499:                    FacesContext context = FacesContext.getCurrentInstance();
0500:                    name = this .getClientId(context).replace(':', '_');
0501:                    name = "EditableList_".concat(name);
0502:                    this .getAttributes().put(JSOBJECT, name);
0503:                }
0504:                return name;
0505:            }
0506:
0507:            private Theme getTheme() {
0508:                return ThemeUtilities.getTheme(FacesContext
0509:                        .getCurrentInstance());
0510:            }
0511:
0512:            public String getOnChange() {
0513:                StringBuffer onchangeBuffer = new StringBuffer(128);
0514:                onchangeBuffer.append(getJavaScriptObjectName());
0515:                onchangeBuffer.append(ENABLE_REMOVE_FUNCTION);
0516:                return onchangeBuffer.toString();
0517:            }
0518:
0519:            public String getPrimaryElementID(FacesContext context) {
0520:
0521:                // This is a little sketchy, because in this case we'd actually prefer
0522:                // to return different values for focus and for the labelled component.
0523:                // We should always label the list (that's the one that should have the
0524:                // invalid icon if the list is empty, for example. But we should
0525:                // probably also set the focus to the top input component which could
0526:                // be either the field or the label. Ah well. I can get around this
0527:                // if I implement some extra bits on the label.
0528:                // TODO
0529:                return getClientId(context).concat(ListSelector.LIST_ID);
0530:            }
0531:
0532:            /**
0533:             * Getter for property valuesToRemove.
0534:             * @return Value of property valuesToRemove.
0535:             */
0536:            public String[] getValuesToRemove() {
0537:                if (valuesToRemove == null) {
0538:                    return new String[0];
0539:                }
0540:                return this .valuesToRemove;
0541:            }
0542:
0543:            /**
0544:             * Setter for property valuesToRemove.
0545:             * @param valuesToRemove New value of property valuesToRemove.
0546:             */
0547:            public void setValuesToRemove(String[] valuesToRemove) {
0548:
0549:                this .valuesToRemove = valuesToRemove;
0550:            }
0551:
0552:            private Label createLabel(String labelString, String id,
0553:                    String facetName) {
0554:
0555:                if (DEBUG)
0556:                    log("createLabel()");
0557:
0558:                // If we find a label, define a component and add it to the
0559:                // children, unless it has been added in a previous cycle
0560:                // (the component is being redisplayed).
0561:
0562:                if (labelString == null || labelString.length() < 1) {
0563:                    // TODO - maybe print a default?
0564:                    labelString = new String();
0565:                }
0566:
0567:                Label label = new Label();
0568:                label.setId(getId().concat(id));
0569:                label.setText(labelString);
0570:                label.setLabelLevel(getLabelLevel());
0571:                this .getFacets().put(facetName, label);
0572:                return label;
0573:            }
0574:
0575:            private StaticText createText(String text, String id,
0576:                    String facetName) {
0577:
0578:                if (DEBUG)
0579:                    log("createText()");
0580:
0581:                // If we find a label, define a component and add it to the
0582:                // children, unless it has been added in a previous cycle
0583:                // (the component is being redisplayed).
0584:
0585:                if (text == null || text.length() < 1) {
0586:                    // TODO - maybe print a default?
0587:                    text = new String();
0588:                }
0589:
0590:                StaticText field = new StaticText();
0591:                field.setValue(text);
0592:                field.setId(getId().concat(id));
0593:                getFacets().put(facetName, field);
0594:                return field;
0595:            }
0596:
0597:            private TextField createField(String id, String facetName) {
0598:
0599:                if (DEBUG)
0600:                    log("createField()");
0601:
0602:                String jsObjectName = getJavaScriptObjectName();
0603:                StringBuffer onkeypressBuffer = new StringBuffer(128);
0604:                onkeypressBuffer.append("if(event.keyCode == 13) { "); //NOI18N      
0605:                onkeypressBuffer.append(jsObjectName);
0606:                onkeypressBuffer.append(ADD_FUNCTION);
0607:                onkeypressBuffer.append("return false; } "); //NOI18N
0608:
0609:                StringBuffer onfocusBuffer = new StringBuffer(128);
0610:                onfocusBuffer.append(jsObjectName);
0611:                onfocusBuffer.append(SET_ADD_DISABLED_FUNCTION);
0612:                onfocusBuffer.append("return false;"); //NOI18N
0613:
0614:                StringBuffer onfocuslostBuffer = new StringBuffer(128);
0615:                onfocuslostBuffer.append(jsObjectName);
0616:                onfocuslostBuffer.append(ENABLE_ADD_FUNCTION);
0617:                onfocuslostBuffer.append("return false;"); //NOI18N
0618:
0619:                TextField field = new TextField();
0620:                field.setId(getId().concat(id));
0621:                int columns = getMaxLength();
0622:                if (columns < MIN_LENGTH) {
0623:                    columns = MIN_LENGTH;
0624:                }
0625:
0626:                field.setColumns(columns);
0627:                field.setOnKeyPress(onkeypressBuffer.toString());
0628:                field.setOnFocus(onfocusBuffer.toString());
0629:                field.setOnBlur(onfocuslostBuffer.toString());
0630:                field.setTrim(true);
0631:                if (getFieldValidator() != null) {
0632:                    field.setValidator(getFieldValidator());
0633:                }
0634:                if (getTabIndex() > 0) {
0635:                    field.setTabIndex(getTabIndex());
0636:                }
0637:
0638:                Theme theme = getTheme();
0639:                StringLengthValidator strl = new StringLengthValidator(
0640:                        getMaxLength(), 1);
0641:                strl.setTooLongMessage(theme
0642:                        .getMessage("EditableList.itemTooLong"));
0643:                strl.setTooShortMessage(theme
0644:                        .getMessage("EditableList.fieldEmpty"));
0645:                field.addValidator(strl);
0646:                getFacets().put(facetName, field);
0647:                return field;
0648:            }
0649:
0650:            private Button createButton(String text, String id,
0651:                    String facetName, ActionListener actionListener) {
0652:
0653:                if (DEBUG)
0654:                    log("createButton()");
0655:
0656:                Button button = new Button();
0657:                button.setId(getId().concat(id));
0658:                button.setText(text);
0659:                if (getTabIndex() > 0) {
0660:                    button.setTabIndex(getTabIndex());
0661:                }
0662:                button.setImmediate(true);
0663:                button.addActionListener(actionListener);
0664:                getFacets().put(facetName, button);
0665:                return button;
0666:            }
0667:
0668:            /**
0669:             * Retrieve an Iterator of ListSelector.ListItem, to be used by the
0670:             * renderer.
0671:             * @return an Iterator over {@link ListItem}.
0672:             * @throws javax.faces.FacesException
0673:             */
0674:            public Iterator getListItems(FacesContext context,
0675:                    boolean rulerAtEnd) throws FacesException {
0676:
0677:                if (DEBUG)
0678:                    log("getListItems()");
0679:
0680:                Locale locale = context.getViewRoot().getLocale();
0681:                if (DEBUG)
0682:                    log("\tLocale is " + locale.toString());
0683:                collator = Collator.getInstance(locale);
0684:                listItems = new TreeMap(collator);
0685:
0686:                // We have to make sure that the long empty list item (whose
0687:                // purpose is to guarantee that the size of the list stays
0688:                // constant) is alwasy at the bottom of the list.  (=has the
0689:                // highest key in the map). We do this by identifying the
0690:                // longest key in the map, as long as the collator is
0691:                // concerned and appending something at the end. (It's not
0692:                // possible to use a constant for this, since an o with an
0693:                // umlaut comes after z in Swedish, but before it in German,
0694:                // for example).
0695:                String lastKey = ""; //NOI18N
0696:                String[] currentValues = getCurrentValueAsStringArray();
0697:                if (DEBUG) {
0698:                    log("\tValues are:");
0699:                    for (int i = 0; i < currentValues.length; ++i) {
0700:                        log(currentValues[i]);
0701:                    }
0702:                }
0703:
0704:                // The string currently being evaluated
0705:                String currentString;
0706:
0707:                // Two cases:
0708:                // First case: the page author requested a sorted map (by
0709:                // character), in which case we sort by the strings
0710:                // themselves. The last key is set to the string that the
0711:                // collator deems to be the last.
0712:                // Second case: the list is sorted by the order they were
0713:                // added to the map. We deal with that by generating a
0714:                // successively longer key for each entry (maps do not
0715:                // conserve the order the items were added). The last key
0716:                // is set to the last key generated.
0717:
0718:                ListItem listItem = null;
0719:                // If the page author does not want the list items to be
0720:                // sorted (alphabetically by locale), then they're
0721:                // supposed to be sorted by the order they were added.
0722:                // Maps are not guaranteed to return items in the order
0723:                // they were added, so we have to create this order
0724:                // artificially. We do that by creating a successively
0725:                // longer key for each element. (a, aa, aaa...).
0726:                StringBuffer unsortedKeyBuffer = new StringBuffer("a"); //NOI18N
0727:                for (int counter = 0; counter < currentValues.length; ++counter) {
0728:                    currentString = currentValues[counter];
0729:                    if (DEBUG) {
0730:                        log("Current string is " + currentString); //NOI18N
0731:                        log("SelectedValue is " + String.valueOf(selectedValue)); //NOI18N
0732:                    }
0733:
0734:                    if (currentString == null) {
0735:                        String msg = MessageUtil.getMessage(
0736:                                "com.sun.rave.web.ui.resources.LogMessages",
0737:                                "EditableList.badValue",
0738:                                new Object[] { getClientId(context) });
0739:                        throw new FacesException(msg);
0740:                    }
0741:
0742:                    listItem = new ListItem(currentString);
0743:                    listItem.setValue(currentString);
0744:                    if (currentString.equals(selectedValue)) {
0745:                        if (DEBUG)
0746:                            log("Selected value");
0747:                        listItem.setSelected(true);
0748:                    }
0749:                    if (isSorted()) {
0750:                        if (collator.compare(currentString, lastKey) > 0) {
0751:                            lastKey = currentString;
0752:                        }
0753:                        listItems.put(currentString, listItem);
0754:                    } else {
0755:                        listItems.put(unsortedKeyBuffer.toString(), listItem);
0756:                        unsortedKeyBuffer.append("a"); //NOI18N
0757:                    }
0758:                }
0759:                if (!isSorted()) {
0760:                    lastKey = unsortedKeyBuffer.toString();
0761:                }
0762:
0763:                // rulerAtEnd will be true if the invoker needs a blank
0764:                // disabled list option at the end. Typically this is
0765:                // needed by the renderer, to guarantee that the widget
0766:                // stays the same in size when items are added and removed.
0767:                if (rulerAtEnd) {
0768:
0769:                    int length = getMaxlLength();
0770:                    if (length < MIN_LENGTH) {
0771:                        length = MIN_LENGTH;
0772:                    }
0773:                    StringBuffer labelBuffer = new StringBuffer(length);
0774:
0775:                    for (int counter = 0; counter < length; ++counter) {
0776:                        labelBuffer.append(SPACER_STRING); //NOI18N
0777:                    }
0778:                    ListItem item = new ListItem(labelBuffer.toString());
0779:                    item.setDisabled(true);
0780:                    listItems.put(lastKey.concat("a"), item); //NOI18N
0781:                }
0782:
0783:                return listItems.values().iterator();
0784:            }
0785:
0786:            private String[] getCurrentValueAsStringArray() {
0787:
0788:                if (DEBUG)
0789:                    log("getCurrentValueAsStringArray()");
0790:                Object value = getSubmittedValue();
0791:                if (value == null) {
0792:                    if (DEBUG)
0793:                        log("\tUsing regular value");
0794:                    value = getValue();
0795:                } else if (DEBUG)
0796:                    log("\tUsing submitted value");
0797:
0798:                if (value == null) {
0799:                    return new String[0];
0800:                }
0801:                if (value instanceof  String[]) {
0802:                    return (String[]) value;
0803:                }
0804:
0805:                String msg = MessageUtil.getMessage(
0806:                        "com.sun.rave.web.ui.resources.LogMessages",
0807:                        "EditableList.badValue",
0808:                        new Object[] { getClientId(FacesContext
0809:                                .getCurrentInstance()) });
0810:                throw new FacesException(msg);
0811:            }
0812:
0813:            private void log(String s) {
0814:                System.out.println(this .getClass().getName() + "::" + s); //NOI18N
0815:            }
0816:
0817:            /**
0818:             * Retrieve the value of this component (the "selected" property) as an
0819:             * object. This method is invoked by the JSF engine during the validation
0820:             * phase. The JSF default behaviour is for components to defer the
0821:             * conversion and validation to the renderer, but for the Selector based
0822:             * components, the renderers do not share as much functionality as the
0823:             * components do, so it is more efficient to do it here.
0824:             * @param context The FacesContext of the request
0825:             * @param submittedValue The submitted value of the component
0826:             */
0827:
0828:            public Object getConvertedValue(FacesContext context,
0829:                    Object submittedValue) throws ConverterException {
0830:
0831:                if (DEBUG)
0832:                    log("getConvertedValue()");
0833:
0834:                if (!(submittedValue instanceof  String[])) {
0835:                    throw new ConverterException(
0836:                            "Submitted value must be a String array");
0837:                }
0838:                String[] rawValues = (String[]) submittedValue;
0839:
0840:                // If there are no elements in rawValues nothing was submitted.
0841:                // If null was rendered, return null
0842:                //
0843:                if (rawValues.length == 0) {
0844:                    if (ConversionUtilities.renderedNull(this )) {
0845:                        return null;
0846:                    }
0847:                }
0848:                return submittedValue;
0849:            }
0850:
0851:            /**
0852:             * @exception NullPointerException
0853:             */
0854:            public void processValidators(FacesContext context) {
0855:
0856:                if (context == null) {
0857:                    throw new NullPointerException();
0858:                }
0859:
0860:                // Skip processing if our rendered flag is false
0861:                if (!isRendered()) {
0862:                    return;
0863:                }
0864:
0865:                // This component may be a developer defined facet.
0866:                // It is explicitly validated during an Add action.
0867:                // It must not be validated during a submit. The assumption
0868:                // is that processValidators is being called during
0869:                // a submit and not in an immediate context.
0870:                // Compare the id of this component with the children
0871:                // and facets and if it matches don't call its
0872:                // processValidators method.
0873:                //
0874:                UIComponent field = getFieldComponent();
0875:                String fieldId = field.getId();
0876:
0877:                // Process all the facets and children of this component
0878:                Iterator kids = getFacetsAndChildren();
0879:                while (kids.hasNext()) {
0880:                    UIComponent kid = (UIComponent) kids.next();
0881:                    // We probably should ensure that fieldId is not
0882:                    // null, during getFieldComponent() even if
0883:                    // it is a developer defined facet.
0884:                    //
0885:                    if (fieldId != null && fieldId.equals(kid.getId())) {
0886:                        continue;
0887:                    }
0888:                    kid.processValidators(context);
0889:                }
0890:
0891:                // Validate the EditableList
0892:                //
0893:                checkValid(context);
0894:            }
0895:
0896:            public void processAddAction() {
0897:
0898:                if (DEBUG)
0899:                    log("processAddAction()");
0900:
0901:                // If we are rendering prematurely don't do anything
0902:                //
0903:                if (FacesContext.getCurrentInstance().getRenderResponse()) {
0904:                    return;
0905:                }
0906:
0907:                selectedValue = null;
0908:
0909:                String[] values = getCurrentValueAsStringArray();
0910:
0911:                Object value = getAddedObject();
0912:                if (value == null) {
0913:                    return;
0914:                }
0915:                //TODO - fix this when implementing conversion for this component
0916:                selectedValue = value.toString();
0917:
0918:                int numValues = values.length;
0919:
0920:                String[] newValues = new String[numValues + 1];
0921:                int counter;
0922:                for (counter = 0; counter < numValues; ++counter) {
0923:                    newValues[counter] = values[counter];
0924:                    if (DEBUG)
0925:                        log("\tAdding " + newValues[counter]);
0926:                }
0927:                newValues[counter] = selectedValue;
0928:                if (DEBUG)
0929:                    log("\tAdding " + newValues[counter]);
0930:                setSubmittedValue(newValues);
0931:            }
0932:
0933:            public void processRemoveAction() {
0934:
0935:                if (DEBUG)
0936:                    log("processRemoveAction()");
0937:
0938:                // If we are rendering prematurely don't do anything
0939:                //
0940:                if (FacesContext.getCurrentInstance().getRenderResponse()) {
0941:                    return;
0942:                }
0943:
0944:                // Reset the selected value
0945:                selectedValue = null;
0946:
0947:                ArrayList items = new ArrayList();
0948:                int counter;
0949:
0950:                if (getValue() != null) {
0951:                    if (DEBUG)
0952:                        log("\tList was not empty");
0953:                    String[] strings = getCurrentValueAsStringArray();
0954:                    int length = strings.length;
0955:                    for (counter = 0; counter < length; ++counter) {
0956:                        items.add(strings[counter]);
0957:                        if (DEBUG)
0958:                            log("Added " + strings[counter]);
0959:                    }
0960:                }
0961:
0962:                String[] valuesToRemove = getValuesToRemove();
0963:                for (counter = 0; counter < valuesToRemove.length; ++counter) {
0964:                    items.remove(valuesToRemove[counter]);
0965:                    if (DEBUG)
0966:                        log("remove " + valuesToRemove[counter]);
0967:                }
0968:
0969:                String[] newValues = new String[items.size()];
0970:                for (counter = 0; counter < items.size(); ++counter) {
0971:                    newValues[counter] = (String) (items.get(counter));
0972:                    if (DEBUG)
0973:                        log("\tAdding back " + newValues[counter]);
0974:                }
0975:
0976:                setValuesToRemove(null);
0977:                setSubmittedValue(newValues);
0978:            }
0979:
0980:            private void checkValid(FacesContext context) {
0981:
0982:                if (DEBUG)
0983:                    log("checkValid()");
0984:
0985:                try {
0986:                    validate(context);
0987:                } catch (RuntimeException e) {
0988:                    if (DEBUG)
0989:                        log("Error during validation");
0990:                    context.renderResponse();
0991:                    throw e;
0992:                }
0993:
0994:                if (!isValid()) {
0995:                    if (DEBUG)
0996:                        log("Component is not valid");
0997:                    context.renderResponse();
0998:                }
0999:            }
1000:
1001:            private Object getAddedObject() {
1002:
1003:                FacesContext context = FacesContext.getCurrentInstance();
1004:
1005:                if (DEBUG)
1006:                    log("\tAdd a new item");
1007:
1008:                // Need to get the field's value validated first
1009:                // The field can't be immediate because we don't want
1010:                // to validate it if the value is not going to be added.
1011:                // For example in a real submit request.
1012:                //
1013:                EditableValueHolder field = (EditableValueHolder) getFieldComponent();
1014:
1015:                // This is ok to do here.
1016:                // We are currently after the APPLY_REQUEST_VALUES phase
1017:                // and before the PROCESS_VALIDATIONS phase.
1018:                // If the field were marked immediate, then the validation
1019:                // would have occured before we get here. If not done
1020:                // here it will be done in the next phase. But it needs
1021:                // to be done here, sort a simulation of immediate
1022:                // henavior. But we don't want the side effect of immediate
1023:                // behavior from external immediate components.
1024:                //
1025:                ((UIComponent) field).processValidators(context);
1026:
1027:                if (!field.isValid()) {
1028:                    return null;
1029:                }
1030:                // Get the value from the field.
1031:                //
1032:                Object value = field.getValue();
1033:
1034:                // This is a policy of the EditableList.
1035:                // An emptyString or null value cannot be added to the list.
1036:                //
1037:                if (value == null
1038:                        || (value instanceof  String && value.toString()
1039:                                .length() == 0)) {
1040:
1041:                    field.setValid(false);
1042:                    context.renderResponse();
1043:
1044:                    if (DEBUG)
1045:                        log("No value from the field");
1046:
1047:                    String message = ThemeUtilities.getTheme(context)
1048:                            .getMessage("EditableList.fieldEmpty");
1049:                    context.addMessage(getClientId(context), new FacesMessage(
1050:                            message));
1051:                    return null;
1052:                }
1053:                // The new value was added so clear the value.
1054:                // This set is questionable, if the field is a developer
1055:                // defined facet. This will cause an update to the model
1056:                // before the value change event.
1057:                //
1058:                if (DEBUG)
1059:                    log("\tFound new value: " + value);
1060:                field.setValue(null);
1061:
1062:                return value;
1063:            }
1064:
1065:            /* Don't need this. Only needed for debugging.
1066:            public void setValue(Object value) {
1067:             
1068:                if(DEBUG) log("setValue()...");
1069:                super.setValue(value);
1070:                if(DEBUG) log("\tLocal value set: " +
1071:                        String.valueOf(isLocalValueSet()));
1072:            }
1073:             */
1074:
1075:            /** Always returns false for EditableList **/
1076:            public boolean isImmediate() {
1077:                return false;
1078:            }
1079:
1080:            /**
1081:             * <p>Return <code>true</code> if the new value is different from the
1082:             * previous value.</p>
1083:             *
1084:             * This only implements a compareValues for value if it is an Array.
1085:             * If value is not an Array, defer to super.compareValues.
1086:             * The assumption is that the ordering of the elements
1087:             * between the previous value and the new value is determined
1088:             * in the same manner.
1089:             *
1090:             * Another assumption is that the two object arguments
1091:             * are of the same type, both arrays of both not arrays.
1092:             *
1093:             * @param previous old value of this component (if any)
1094:             * @param value new value of this component (if any)
1095:             */
1096:            protected boolean compareValues(Object previous, Object value) {
1097:
1098:                // Let super take care of null cases
1099:                //
1100:                if (previous == null || value == null) {
1101:                    return super .compareValues(previous, value);
1102:                }
1103:                if (value instanceof  Object[]) {
1104:                    // If the lengths aren't equal return true
1105:                    //
1106:                    int length = Array.getLength(value);
1107:                    if (Array.getLength(previous) != length) {
1108:                        return true;
1109:                    }
1110:                    // Each element at index "i" in previous must be equal to the
1111:                    // elementa at index "i" in value.
1112:                    //
1113:                    for (int i = 0; i < length; ++i) {
1114:
1115:                        Object newValue = Array.get(value, i);
1116:                        Object prevValue = Array.get(previous, i);
1117:
1118:                        // This is probably not necessary since
1119:                        // an Option's value cannot be null
1120:                        //
1121:                        if (newValue == null) {
1122:                            if (prevValue == null) {
1123:                                continue;
1124:                            } else {
1125:                                return true;
1126:                            }
1127:                        }
1128:                        if (prevValue == null) {
1129:                            return true;
1130:                        }
1131:
1132:                        if (!prevValue.equals(newValue)) {
1133:                            return true;
1134:                        }
1135:                    }
1136:                    return false;
1137:                }
1138:                return super .compareValues(previous, value);
1139:            }
1140:
1141:            public String[] getValueAsStringArray(FacesContext context) {
1142:
1143:                if (DEBUG)
1144:                    log("getValueAsStringArray)");
1145:
1146:                Iterator iterator = getListItems(context, false);
1147:                int numItems = listItems.size();
1148:                String[] values = new String[numItems];
1149:
1150:                int counter = 0;
1151:                while (counter < numItems) {
1152:                    values[counter] = ((ListItem) (iterator.next())).getValue();
1153:                    ++counter;
1154:                }
1155:                return values;
1156:            }
1157:
1158:            public boolean mainListSubmits() {
1159:                return true;
1160:            }
1161:        }
1162:
1163:        class AddListener implements  ActionListener, Serializable {
1164:
1165:            public void processAction(ActionEvent event) {
1166:
1167:                UIComponent comp = event.getComponent();
1168:                comp = comp.getParent();
1169:                if (comp instanceof  EditableList) {
1170:                    ((EditableList) comp).processAddAction();
1171:                }
1172:            }
1173:        }
1174:
1175:        class RemoveListener implements  ActionListener, Serializable {
1176:
1177:            public void processAction(ActionEvent event) {
1178:
1179:                UIComponent comp = event.getComponent();
1180:                comp = comp.getParent();
1181:                if (comp instanceof  EditableList) {
1182:                    ((EditableList) comp).processRemoveAction();
1183:                }
1184:            }
1185:
1186:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.