Source Code Cross Referenced for FormComponent.java in  » J2EE » wicket » org » apache » wicket » markup » html » form » 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 » J2EE » wicket » org.apache.wicket.markup.html.form 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.wicket.markup.html.form;
0018:
0019:        import java.text.Format;
0020:        import java.text.SimpleDateFormat;
0021:        import java.util.ArrayList;
0022:        import java.util.Collections;
0023:        import java.util.HashMap;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.Locale;
0027:        import java.util.Map;
0028:
0029:        import org.apache.wicket.Application;
0030:        import org.apache.wicket.Component;
0031:        import org.apache.wicket.Localizer;
0032:        import org.apache.wicket.MarkupContainer;
0033:        import org.apache.wicket.Page;
0034:        import org.apache.wicket.WicketRuntimeException;
0035:        import org.apache.wicket.markup.ComponentTag;
0036:        import org.apache.wicket.model.IModel;
0037:        import org.apache.wicket.util.convert.ConversionException;
0038:        import org.apache.wicket.util.convert.IConverter;
0039:        import org.apache.wicket.util.lang.Classes;
0040:        import org.apache.wicket.util.string.PrependingStringBuffer;
0041:        import org.apache.wicket.util.string.StringList;
0042:        import org.apache.wicket.util.string.Strings;
0043:        import org.apache.wicket.util.string.interpolator.MapVariableInterpolator;
0044:        import org.apache.wicket.validation.IErrorMessageSource;
0045:        import org.apache.wicket.validation.INullAcceptingValidator;
0046:        import org.apache.wicket.validation.IValidatable;
0047:        import org.apache.wicket.validation.IValidationError;
0048:        import org.apache.wicket.validation.IValidator;
0049:        import org.apache.wicket.validation.IValidatorAddListener;
0050:        import org.apache.wicket.validation.ValidationError;
0051:        import org.apache.wicket.version.undo.Change;
0052:
0053:        /**
0054:         * An HTML form component knows how to validate itself. Validators that
0055:         * implement IValidator can be added to the component. They will be evaluated in
0056:         * the order they were added and the first Validator that returns an error
0057:         * message determines the error message returned by the component.
0058:         * <p>
0059:         * FormComponents are not versioned by default. If you need versioning for your
0060:         * FormComponents, you will need to call Form.setVersioned(true), which will set
0061:         * versioning on for the form and all form component children.
0062:         * <p>
0063:         * If this component is required and that fails, the error key that is used is
0064:         * the "Required"; if the type conversion fails, it will use the key
0065:         * "IConverter". The keys that can be used in both are:
0066:         * <ul>
0067:         * <li>${input}: the input the user did give</li>
0068:         * <li>${name}: the name of the component that failed</li>
0069:         * <li>${label}: the label of the component</li>
0070:         * </ul>
0071:         * 
0072:         * @author Jonathan Locke
0073:         * @author Eelco Hillenius
0074:         * @author Johan Compagner
0075:         * @author Igor Vaynberg (ivaynberg)
0076:         */
0077:        public abstract class FormComponent extends LabeledWebMarkupContainer
0078:                implements  IFormVisitorParticipant {
0079:            /**
0080:             * Visitor for traversing form components
0081:             */
0082:            public static abstract class AbstractVisitor implements  IVisitor {
0083:                /**
0084:                 * @see org.apache.wicket.markup.html.form.FormComponent.IVisitor#formComponent(org.apache.wicket.markup.html.form.FormComponent)
0085:                 */
0086:                public Object formComponent(IFormVisitorParticipant component) {
0087:                    if (component instanceof  FormComponent) {
0088:                        onFormComponent((FormComponent) component);
0089:                    }
0090:                    return Component.IVisitor.CONTINUE_TRAVERSAL;
0091:                }
0092:
0093:                protected abstract void onFormComponent(
0094:                        FormComponent formComponent);
0095:            }
0096:
0097:            /**
0098:             * Typesafe interface to code that is called when visiting a form component.
0099:             */
0100:            public static interface IVisitor {
0101:                /**
0102:                 * Called when visiting a form component
0103:                 * 
0104:                 * @param formComponent
0105:                 *            The form component
0106:                 * @return component
0107:                 */
0108:                public Object formComponent(
0109:                        IFormVisitorParticipant formComponent);
0110:            }
0111:
0112:            /**
0113:             * {@link IErrorMessageSource} used for error messags against this form
0114:             * components.
0115:             * 
0116:             * @author ivaynberg
0117:             */
0118:            private class MessageSource implements  IErrorMessageSource {
0119:
0120:                /**
0121:                 * @see org.apache.wicket.validation.IErrorMessageSource#getMessage(java.lang.String)
0122:                 */
0123:                public String getMessage(String key) {
0124:                    final FormComponent formComponent = FormComponent.this ;
0125:
0126:                    // retrieve prefix that will be used to construct message keys
0127:                    String prefix = formComponent.getValidatorKeyPrefix();
0128:                    if (Strings.isEmpty(prefix)) {
0129:                        prefix = "";
0130:                    }
0131:
0132:                    final Localizer localizer = formComponent.getLocalizer();
0133:
0134:                    String resource = prefix + getId() + "." + key;
0135:
0136:                    // First use the parent for resolving so that
0137:                    // form1.textfield1.Required can be used.
0138:
0139:                    // Note: It is important that the default value of "" is provided
0140:                    // to getString() not to throw a MissingResourceException or to
0141:                    // return a default string like "[Warning: String ..."
0142:                    String message = localizer.getString(resource,
0143:                            formComponent.getParent(), "");
0144:
0145:                    // If not found, than ...
0146:                    if (Strings.isEmpty(message)) {
0147:                        // Try a variation of the resource key
0148:
0149:                        resource = prefix + key;
0150:
0151:                        message = localizer.getString(resource, formComponent
0152:                                .getParent(), "");
0153:                    }
0154:
0155:                    if (Strings.isEmpty(message)) {
0156:                        // If still empty then use default
0157:
0158:                        resource = prefix + getId() + "." + key;
0159:
0160:                        // Note: It is important that the default value of "" is
0161:                        // provided
0162:                        // to getString() not to throw a MissingResourceException or to
0163:                        // return a default string like "[Warning: String ..."
0164:                        message = localizer.getString(resource, formComponent,
0165:                                "");
0166:
0167:                        // If not found, than ...
0168:                        if (Strings.isEmpty(message)) {
0169:                            // Try a variation of the resource key
0170:
0171:                            resource = prefix + key;
0172:
0173:                            message = localizer.getString(resource,
0174:                                    formComponent, "");
0175:                        }
0176:                    }
0177:
0178:                    // convert empty string to null in case our default value of "" was
0179:                    // returned from localizer
0180:                    if (Strings.isEmpty(message)) {
0181:                        message = null;
0182:                    }
0183:                    return message;
0184:                }
0185:
0186:                /**
0187:                 * @see org.apache.wicket.validation.IErrorMessageSource#substitute(java.lang.String,
0188:                 *      java.util.Map)
0189:                 */
0190:                public String substitute(String string, Map vars)
0191:                        throws IllegalStateException {
0192:                    return new MapVariableInterpolator(string,
0193:                            addDefaultVars(vars), Application.get()
0194:                                    .getResourceSettings()
0195:                                    .getThrowExceptionOnMissingResource())
0196:                            .toString();
0197:                }
0198:
0199:                /**
0200:                 * Creates a new params map that additionaly contains the default input,
0201:                 * name, label parameters
0202:                 * 
0203:                 * @param params
0204:                 *            original params map
0205:                 * @return new params map
0206:                 */
0207:                private Map addDefaultVars(Map params) {
0208:                    // create and fill the new params map
0209:                    final HashMap fullParams;
0210:                    if (params == null) {
0211:                        fullParams = new HashMap(6);
0212:                    } else {
0213:                        fullParams = new HashMap(params.size() + 6);
0214:                        fullParams.putAll(params);
0215:                    }
0216:
0217:                    // add the input param if not already present
0218:                    if (!fullParams.containsKey("input")) {
0219:                        fullParams.put("input", getInput());
0220:                    }
0221:
0222:                    // add the name param if not already present
0223:                    if (!fullParams.containsKey("name")) {
0224:                        fullParams.put("name", getId());
0225:                    }
0226:
0227:                    // add the label param if not already present
0228:                    if (!fullParams.containsKey("label")) {
0229:                        fullParams.put("label", getLabel());
0230:                    }
0231:                    return fullParams;
0232:                }
0233:
0234:                /**
0235:                 * @return value of label param for this form component
0236:                 */
0237:                private Object getLabel() {
0238:                    final FormComponent fc = FormComponent.this ;
0239:                    Object label = null;
0240:
0241:                    // first try the label model ...
0242:                    if (fc.getLabel() != null) {
0243:                        label = fc.getLabel().getObject();
0244:                    }
0245:                    // ... then try a resource of format [form-component-id] with
0246:                    // default of '[form-component-id]'
0247:                    if (label == null) {
0248:
0249:                        label = fc.getLocalizer().getString(fc.getId(),
0250:                                fc.getParent(), fc.getId());
0251:                    }
0252:                    return label;
0253:                }
0254:            }
0255:
0256:            /**
0257:             * Change object to capture the required flag change
0258:             * 
0259:             * @author Igor Vaynberg (ivaynberg)
0260:             */
0261:            private final class RequiredStateChange extends Change {
0262:                private static final long serialVersionUID = 1L;
0263:
0264:                private final boolean required = isRequired();
0265:
0266:                /**
0267:                 * @see org.apache.wicket.version.undo.Change#undo()
0268:                 */
0269:                public void undo() {
0270:                    setRequired(required);
0271:                }
0272:            }
0273:
0274:            /**
0275:             * Adapter that makes this component appear as {@link IValidatable}
0276:             * 
0277:             * @author ivaynberg
0278:             */
0279:            private class ValidatableAdapter implements  IValidatable {
0280:
0281:                /**
0282:                 * @see org.apache.wicket.validation.IValidatable#error(org.apache.wicket.validation.IValidationError)
0283:                 */
0284:                public void error(IValidationError error) {
0285:                    FormComponent.this .error(error);
0286:                }
0287:
0288:                /**
0289:                 * @see org.apache.wicket.validation.IValidatable#getValue()
0290:                 */
0291:                public Object getValue() {
0292:                    return getConvertedInput();
0293:                }
0294:
0295:                public boolean isValid() {
0296:                    return FormComponent.this .isValid();
0297:                }
0298:
0299:            }
0300:
0301:            /**
0302:             * The value separator
0303:             */
0304:            public static String VALUE_SEPARATOR = ";";
0305:
0306:            private static final String[] EMPTY_STRING_ARRAY = new String[] { "" };
0307:
0308:            /**
0309:             * Whether this form component should save and restore state between
0310:             * sessions. This is false by default.
0311:             */
0312:            private static final short FLAG_PERSISTENT = FLAG_RESERVED2;
0313:
0314:            /** Whether or not this component's value is required (non-empty) */
0315:            private static final short FLAG_REQUIRED = FLAG_RESERVED3;
0316:
0317:            private static final String NO_RAW_INPUT = "[-NO-RAW-INPUT-]";
0318:
0319:            private static final long serialVersionUID = 1L;
0320:
0321:            /**
0322:             * Make empty strings null values boolean. Used by AbstractTextComponent
0323:             * subclass.
0324:             */
0325:            protected static final short FLAG_CONVERT_EMPTY_INPUT_STRING_TO_NULL = FLAG_RESERVED1;
0326:
0327:            /**
0328:             * Visits any form components inside component if it is a container, or
0329:             * component itself if it is itself a form component
0330:             * 
0331:             * @param component
0332:             *            starting point of the traversal
0333:             * 
0334:             * @param visitor
0335:             *            The visitor to call
0336:             */
0337:            public static final void visitFormComponentsPostOrder(
0338:                    Component component, final FormComponent.IVisitor visitor) {
0339:                if (visitor == null) {
0340:                    throw new IllegalArgumentException(
0341:                            "Argument `visitor` cannot be null");
0342:                }
0343:
0344:                visitFormComponentsPostOrderHelper(component, visitor);
0345:            }
0346:
0347:            private static final Object visitFormComponentsPostOrderHelper(
0348:                    Component component, final FormComponent.IVisitor visitor) {
0349:                if (component instanceof  MarkupContainer) {
0350:                    final MarkupContainer container = (MarkupContainer) component;
0351:                    if (container.size() > 0) {
0352:                        boolean visitChildren = true;
0353:                        if (container instanceof  IFormVisitorParticipant) {
0354:                            visitChildren = ((IFormVisitorParticipant) container)
0355:                                    .processChildren();
0356:                        }
0357:                        if (visitChildren) {
0358:                            final Iterator children = container.iterator();
0359:                            while (children.hasNext()) {
0360:                                final Component child = (Component) children
0361:                                        .next();
0362:                                Object value = visitFormComponentsPostOrderHelper(
0363:                                        child, visitor);
0364:                                if (value == Component.IVisitor.STOP_TRAVERSAL) {
0365:                                    return value;
0366:                                }
0367:                            }
0368:                        }
0369:                    }
0370:                }
0371:
0372:                if (component instanceof  FormComponent) {
0373:                    final FormComponent fc = (FormComponent) component;
0374:                    return visitor.formComponent(fc);
0375:                }
0376:
0377:                return null;
0378:            }
0379:
0380:            private transient Object convertedInput;
0381:
0382:            /**
0383:             * Raw Input entered by the user or NO_RAW_INPUT if nothing is filled in.
0384:             */
0385:            private String rawInput = NO_RAW_INPUT;
0386:
0387:            /**
0388:             * Type that the raw input string will be converted to
0389:             */
0390:            private String typeName;
0391:
0392:            /**
0393:             * The list of validators for this form component as either an IValidator
0394:             * instance or an array of IValidator instances.
0395:             */
0396:            private Object validators = null;
0397:
0398:            /**
0399:             * @see org.apache.wicket.Component#Component(String)
0400:             */
0401:            public FormComponent(final String id) {
0402:                super (id);
0403:                // the form decides whether form components are versioned or not
0404:                // see Form.setVersioned
0405:                setVersioned(false);
0406:            }
0407:
0408:            /**
0409:             * @see org.apache.wicket.Component#Component(String, IModel)
0410:             */
0411:            public FormComponent(final String id, IModel model) {
0412:                super (id, model);
0413:                // the form decides whether form components are versioned or not
0414:                // see Form.setVersioned
0415:                setVersioned(false);
0416:            }
0417:
0418:            /**
0419:             * Adds a validator to this form component.
0420:             * 
0421:             * @param validator
0422:             *            The validator
0423:             * @return This
0424:             * @throws IllegalArgumentException
0425:             *             if validator is null
0426:             * @see IValidator
0427:             * @see IValidatorAddListener
0428:             */
0429:            public final FormComponent add(final IValidator validator) {
0430:                if (validator == null) {
0431:                    throw new IllegalArgumentException(
0432:                            "validator argument cannot be null");
0433:                }
0434:
0435:                // add the validator
0436:                validators_add(validator);
0437:
0438:                // see whether the validator listens for add events
0439:                if (validator instanceof  IValidatorAddListener) {
0440:                    ((IValidatorAddListener) validator).onAdded(this );
0441:                }
0442:
0443:                // return this for chaining
0444:                return this ;
0445:            }
0446:
0447:            /**
0448:             * Checks if the form component's 'required' requirement is met. This method
0449:             * should typically only be called when {@link #isRequired()} returns true.
0450:             * 
0451:             * @return true if the 'required' requirement is met, false otherwise
0452:             */
0453:            public boolean checkRequired() {
0454:                if (isRequired()) {
0455:                    final String input = getInput();
0456:
0457:                    // when null, check whether this is natural for that component, or
0458:                    // whether - as is the case with text fields - this can only happen
0459:                    // when the component was disabled
0460:                    if (input == null && !isInputNullable()) {
0461:                        // this value must have come from a disabled field
0462:                        // do not perform validation
0463:                        return true;
0464:                    }
0465:
0466:                    // peform validation by looking whether the value is null or empty
0467:                    return !Strings.isEmpty(input);
0468:                }
0469:                return true;
0470:            }
0471:
0472:            /**
0473:             * Clears the user input.
0474:             */
0475:            public final void clearInput() {
0476:                rawInput = NO_RAW_INPUT;
0477:            }
0478:
0479:            /**
0480:             * Reports a validation error against this form component.
0481:             * 
0482:             * The actual error is reported by creating a
0483:             * {@link ValidationErrorFeedback} object that holds both the validation
0484:             * error and the generated error message - so a custom feedback panel can
0485:             * have access to both.
0486:             * 
0487:             * @param error
0488:             *            validation error
0489:             */
0490:            public void error(IValidationError error) {
0491:                if (error == null) {
0492:                    throw new IllegalArgumentException(
0493:                            "Argument [[error]] cannot be null");
0494:                }
0495:                String message = error.getErrorMessage(new MessageSource());
0496:
0497:                if (message == null) {
0498:                    // XXX maybe make message source remember tried resource keys so a
0499:                    // more detailederror message can be created - like show which keys
0500:                    // were tried
0501:                    message = "Could not locate error message for error: "
0502:                            + error.toString();
0503:                }
0504:                error(new ValidationErrorFeedback(error, message));
0505:            }
0506:
0507:            /**
0508:             * Gets the converted input. The converted input is set earlier though the
0509:             * implementation of {@link #convertInput()}.
0510:             * 
0511:             * @return value of input possibly converted into an appropriate type
0512:             */
0513:            public final Object getConvertedInput() {
0514:                return convertedInput;
0515:            }
0516:
0517:            /**
0518:             * Sets the converted input. This method is typically not called by clients,
0519:             * unless they override {@link #convertInput()}, in which case they should
0520:             * call this method to update the input for this component instance.
0521:             * 
0522:             * @param convertedInput
0523:             *            the converted input
0524:             */
0525:            public final void setConvertedInput(Object convertedInput) {
0526:                this .convertedInput = convertedInput;
0527:            }
0528:
0529:            /**
0530:             * @return The parent form for this form component
0531:             */
0532:            public Form getForm() {
0533:                // Look for parent form
0534:                final Form form = (Form) findParent(Form.class);
0535:                if (form == null) {
0536:                    throw new WicketRuntimeException(
0537:                            "Could not find Form parent for " + this );
0538:                }
0539:                return form;
0540:            }
0541:
0542:            /**
0543:             * Gets the request parameter for this component as a string.
0544:             * 
0545:             * @return The value in the request for this component
0546:             */
0547:            public String getInput() {
0548:                String[] input = getInputAsArray();
0549:                if (input == null || input.length == 0) {
0550:                    return null;
0551:                } else {
0552:                    return input[0];
0553:                }
0554:            }
0555:
0556:            /**
0557:             * Gets the request parameters for this component as strings.
0558:             * 
0559:             * @return The values in the request for this component
0560:             */
0561:            public String[] getInputAsArray() {
0562:                String[] values = getRequest().getParameters(getInputName());
0563:                if (!isInputNullable()) {
0564:                    if (values != null && values.length == 1
0565:                            && values[0] == null) {
0566:                        // we the key got passed in (otherwise values would be null),
0567:                        // but the value was set to null.
0568:                        // As the servlet spec isn't clear on what to do with 'empty'
0569:                        // request values - most return an empty string, but some null -
0570:                        // we have to workaround here and deliberately set to an empty
0571:                        // string if the the component is not nullable (text components)
0572:                        return EMPTY_STRING_ARRAY;
0573:                    }
0574:                }
0575:                return values;
0576:            }
0577:
0578:            /**
0579:             * Gets the string to be used for the <tt>name</tt> attribute of the form
0580:             * element. Generated using the path from the form to the component,
0581:             * excluding the form itself. Override it if you want even a smaller name.
0582:             * E.g. if you know for sure that the id is unique within a form.
0583:             * 
0584:             * @return The string to use as the form element's name attribute
0585:             */
0586:            public String getInputName() {
0587:                String id = getId();
0588:                final PrependingStringBuffer inputName = new PrependingStringBuffer(
0589:                        id.length());
0590:                Component c = this ;
0591:                while (true) {
0592:                    inputName.prepend(id);
0593:                    c = c.getParent();
0594:                    if (c == null
0595:                            || (c instanceof  Form && ((Form) c).isRootForm())
0596:                            || c instanceof  Page) {
0597:                        break;
0598:                    }
0599:                    inputName.prepend(Component.PATH_SEPARATOR);
0600:                    id = c.getId();
0601:                }
0602:
0603:                // having input name "submit" causes problems with javascript, so we
0604:                // create a unique string to replace it by prepending a path separator
0605:                if (inputName.equals("submit")) {
0606:                    inputName.prepend(Component.PATH_SEPARATOR);
0607:                }
0608:                return inputName.toString();
0609:            }
0610:
0611:            /**
0612:             * Use hasRawInput() to check if this component has raw input because null
0613:             * can mean 2 things: It doesn't have rawinput or the rawinput is really
0614:             * null.
0615:             * 
0616:             * @return The raw form input that is stored for this formcomponent
0617:             */
0618:            public final String getRawInput() {
0619:                return rawInput == NO_RAW_INPUT ? null : rawInput;
0620:            }
0621:
0622:            /**
0623:             * @return the type to use when updating the model for this form component
0624:             */
0625:            public final Class getType() {
0626:                return typeName == null ? null : Classes.resolveClass(typeName);
0627:            }
0628:
0629:            /**
0630:             * @see Form#getValidatorKeyPrefix()
0631:             * @return prefix used when constructing validator key messages
0632:             */
0633:            public String getValidatorKeyPrefix() {
0634:                Form form = (Form) findParent(Form.class);
0635:                if (form != null) {
0636:                    return getForm().getValidatorKeyPrefix();
0637:                }
0638:                return null;
0639:            }
0640:
0641:            /**
0642:             * Gets an unmodifiable list of validators for this FormComponent.
0643:             * 
0644:             * @return List of validators
0645:             */
0646:            public final List getValidators() {
0647:                final int size = validators_size();
0648:                if (size == 0) {
0649:                    return Collections.EMPTY_LIST;
0650:                } else {
0651:                    final List list = new ArrayList(size);
0652:                    for (int i = 0; i < size; i++) {
0653:                        list.add(validators_get(i));
0654:                    }
0655:                    return Collections.unmodifiableList(list);
0656:                }
0657:            }
0658:
0659:            /**
0660:             * Gets current value for a form component, which can be either input data
0661:             * entered by the user, or the component's model object if no input was
0662:             * provided.
0663:             * 
0664:             * @return The value
0665:             */
0666:            public final String getValue() {
0667:                if (NO_RAW_INPUT.equals(rawInput)) {
0668:                    return getModelValue();
0669:                } else {
0670:                    if (getEscapeModelStrings() && rawInput != null) {
0671:                        return Strings.escapeMarkup(rawInput).toString();
0672:                    }
0673:                    return rawInput;
0674:                }
0675:            }
0676:
0677:            /**
0678:             * Returns whether this component has raw input. Raw input is unconverted
0679:             * input straight from the client.
0680:             * 
0681:             * @return boolean whether this component has raw input.
0682:             */
0683:            public final boolean hasRawInput() {
0684:                return rawInput != NO_RAW_INPUT;
0685:            }
0686:
0687:            /**
0688:             * Used by Form to tell the FormComponent that a new user input is available
0689:             */
0690:            public final void inputChanged() {
0691:                if (isVisibleInHierarchy() && isEnabled()) {
0692:                    // Get input as String array
0693:                    final String[] input = getInputAsArray();
0694:
0695:                    // If there is any input
0696:                    if (input != null && input.length > 0 && input[0] != null) {
0697:                        // join the values together with ";", for example, "id1;id2;id3"
0698:                        rawInput = StringList.valueOf(input).join(
0699:                                VALUE_SEPARATOR);
0700:                    } else if (isInputNullable()) {
0701:                        // no input
0702:                        rawInput = null;
0703:                    } else {
0704:                        rawInput = NO_RAW_INPUT;
0705:                    }
0706:                }
0707:            }
0708:
0709:            /**
0710:             * Indicate that validation of this form component failed.
0711:             */
0712:            public final void invalid() {
0713:                onInvalid();
0714:            }
0715:
0716:            /**
0717:             * Gets whether this component's input can be null. By default, components
0718:             * that do not get input will have null values passed in for input. However,
0719:             * component TextField is an example (possibly the only one) that never gets
0720:             * a null passed in, even if the field is left empty UNLESS it had attribute
0721:             * <code>disabled="disabled"</code> set.
0722:             * 
0723:             * @return True if this component's input can be null. Returns true by
0724:             *         default.
0725:             */
0726:            public boolean isInputNullable() {
0727:                return true;
0728:            }
0729:
0730:            /**
0731:             * @return True if this component encodes data in a multipart form submit
0732:             */
0733:            public boolean isMultiPart() {
0734:                return false;
0735:            }
0736:
0737:            /**
0738:             * @return True if this component supports persistence AND it has been asked
0739:             *         to persist itself with setPersistent().
0740:             */
0741:            public final boolean isPersistent() {
0742:                return supportsPersistence() && getFlag(FLAG_PERSISTENT);
0743:            }
0744:
0745:            /**
0746:             * @return whether or not this component's value is required
0747:             */
0748:            public boolean isRequired() {
0749:                return getFlag(FLAG_REQUIRED);
0750:            }
0751:
0752:            /**
0753:             * Gets whether this component is 'valid'. Valid in this context means that
0754:             * no validation errors were reported the last time the form component was
0755:             * processed. This variable not only is convenient for 'business' use, but
0756:             * is also nescesarry as we don't want the form component models updated
0757:             * with invalid input.
0758:             * 
0759:             * @return valid whether this component is 'valid'
0760:             */
0761:            public final boolean isValid() {
0762:                class IsValidVisitor implements  IVisitor {
0763:                    boolean valid = true;
0764:
0765:                    public Object formComponent(
0766:                            IFormVisitorParticipant formComponent) {
0767:                        final FormComponent fc = (FormComponent) formComponent;
0768:                        if (fc.hasErrorMessage()) {
0769:                            valid = false;
0770:                            return Component.IVisitor.STOP_TRAVERSAL;
0771:                        }
0772:                        return Component.IVisitor.CONTINUE_TRAVERSAL;
0773:                    }
0774:                }
0775:                IsValidVisitor tmp = new IsValidVisitor();
0776:                visitFormComponentsPostOrder(this , tmp);
0777:                return tmp.valid;
0778:            }
0779:
0780:            /**
0781:             * @see org.apache.wicket.markup.html.form.IFormVisitorParticipant#processChildren(boolean)
0782:             */
0783:            public boolean processChildren() {
0784:                return true;
0785:            }
0786:
0787:            /**
0788:             * This method will retrieve the request parameter, validate it, and if
0789:             * valid update the model. These are the same steps as would be performed by
0790:             * the form.
0791:             * 
0792:             * This is useful when a formcomponent is used outside a form.
0793:             * 
0794:             */
0795:            public final void processInput() {
0796:                inputChanged();
0797:                validate();
0798:                if (hasErrorMessage()) {
0799:                    invalid();
0800:                } else {
0801:                    valid();
0802:                    updateModel();
0803:                }
0804:            }
0805:
0806:            /**
0807:             * The value will be made available to the validator property by means of
0808:             * ${label}. It does not have any specific meaning to FormComponent itself.
0809:             * 
0810:             * @param labelModel
0811:             * @return this for chaining
0812:             */
0813:            public FormComponent setLabel(IModel labelModel) {
0814:                setLabelInternal(labelModel);
0815:                return this ;
0816:            }
0817:
0818:            /**
0819:             * Sets the value for a form component this value will be split the string
0820:             * with {@link FormComponent#VALUE_SEPARATOR} and calls
0821:             * setModelValue(String[]) with that.
0822:             * 
0823:             * @param value
0824:             *            The value
0825:             * 
0826:             * @deprecated call or override setModelValue(String[])
0827:             */
0828:            public void setModelValue(final String value) {
0829:                setModelValue(value.split(VALUE_SEPARATOR));
0830:            }
0831:
0832:            /**
0833:             * Sets the value for a form component.
0834:             * 
0835:             * @param value
0836:             *            The value
0837:             */
0838:            public void setModelValue(final String[] value) {
0839:                convertedInput = convertValue(value);
0840:                updateModel();
0841:            }
0842:
0843:            /**
0844:             * Sets whether this component is to be persisted.
0845:             * 
0846:             * @param persistent
0847:             *            True if this component is to be persisted.
0848:             * @return this for chaining
0849:             */
0850:            public final FormComponent setPersistent(final boolean persistent) {
0851:                if (supportsPersistence()) {
0852:                    setFlag(FLAG_PERSISTENT, persistent);
0853:                } else {
0854:                    throw new UnsupportedOperationException("FormComponent "
0855:                            + getClass() + " does not support cookies");
0856:                }
0857:                return this ;
0858:            }
0859:
0860:            /**
0861:             * Sets the required flag
0862:             * 
0863:             * @param required
0864:             * @return this for chaining
0865:             */
0866:            public final FormComponent setRequired(final boolean required) {
0867:                if (!required && getType() != null && getType().isPrimitive()) {
0868:                    throw new WicketRuntimeException(
0869:                            "FormComponent can't be not required when the type is primitive class: "
0870:                                    + this );
0871:                }
0872:                if (required != isRequired()) {
0873:                    addStateChange(new RequiredStateChange());
0874:                }
0875:                setFlag(FLAG_REQUIRED, required);
0876:                return this ;
0877:            }
0878:
0879:            /**
0880:             * Sets the type that will be used when updating the model for this
0881:             * component. If no type is specified String type is assumed.
0882:             * 
0883:             * @param type
0884:             * @return this for chaining
0885:             */
0886:            public final FormComponent setType(Class type) {
0887:                typeName = type == null ? null : type.getName();
0888:                if (type != null && type.isPrimitive()) {
0889:                    setRequired(true);
0890:                }
0891:                return this ;
0892:            }
0893:
0894:            /**
0895:             * Updates this components' model from the request, it expect that the
0896:             * object is already converted through the convert() call. By default it
0897:             * just does this:
0898:             * 
0899:             * <pre>
0900:             * setModelObject(getConvertedInput());
0901:             * </pre>
0902:             * 
0903:             * DO NOT CALL THIS METHOD DIRECTLY UNLESS YOU ARE SURE WHAT YOU ARE DOING.
0904:             * USUALLY UPDATING YOUR MODEL IS HANDLED BY THE FORM, NOT DIRECTLY BY YOU.
0905:             */
0906:            public void updateModel() {
0907:                setModelObject(getConvertedInput());
0908:            }
0909:
0910:            /**
0911:             * Called to indicate that the user input is valid.
0912:             */
0913:            public final void valid() {
0914:                clearInput();
0915:
0916:                onValid();
0917:            }
0918:
0919:            /**
0920:             * Performs full validation of the form component, which consists of calling
0921:             * validateRequired(), validateTypeConversion(), and validateValidators().
0922:             * This method should only be used if the form component needs to be fully
0923:             * validated outside the form process.
0924:             */
0925:            public final void validate() {
0926:                validateRequired();
0927:                if (isValid()) {
0928:                    convertInput();
0929:
0930:                    if (isValid() && isRequired()
0931:                            && getConvertedInput() == null && isInputNullable()) {
0932:                        reportRequiredError();
0933:                    }
0934:
0935:                    if (isValid()) {
0936:                        validateValidators();
0937:                    }
0938:                }
0939:            }
0940:
0941:            /**
0942:             * @param validator
0943:             *            The validator to add to the validators Object (which may be an
0944:             *            array of IValidators or a single instance, for efficiency)
0945:             */
0946:            private void validators_add(final IValidator validator) {
0947:                if (validators == null) {
0948:                    validators = validator;
0949:                } else {
0950:                    // Get current list size
0951:                    final int size = validators_size();
0952:
0953:                    // Create array that holds size + 1 elements
0954:                    final IValidator[] validators = new IValidator[size + 1];
0955:
0956:                    // Loop through existing validators copying them
0957:                    for (int i = 0; i < size; i++) {
0958:                        validators[i] = validators_get(i);
0959:                    }
0960:
0961:                    // Add new validator to the end
0962:                    validators[size] = validator;
0963:
0964:                    // Save new validator list
0965:                    this .validators = validators;
0966:                }
0967:            }
0968:
0969:            /**
0970:             * Gets validator from validators Object (which may be an array of
0971:             * IValidators or a single instance, for efficiency) at the given index
0972:             * 
0973:             * @param index
0974:             *            The index of the validator to get
0975:             * @return The validator
0976:             */
0977:            private IValidator validators_get(int index) {
0978:                if (validators == null) {
0979:                    throw new IndexOutOfBoundsException();
0980:                }
0981:                if (validators instanceof  IValidator[]) {
0982:                    return ((IValidator[]) validators)[index];
0983:                }
0984:                return (IValidator) validators;
0985:            }
0986:
0987:            /**
0988:             * @return The number of validators in the validators Object (which may be
0989:             *         an array of IValidators or a single instance, for efficiency)
0990:             */
0991:            private int validators_size() {
0992:                if (validators == null) {
0993:                    return 0;
0994:                }
0995:                if (validators instanceof  IValidator[]) {
0996:                    return ((IValidator[]) validators).length;
0997:                }
0998:                return 1;
0999:            }
1000:
1001:            /**
1002:             * Converts and validates the conversion of the raw input string into the
1003:             * object specified by {@link FormComponent#getType()} and records any
1004:             * errors. Converted value is available through
1005:             * {@link FormComponent#getConvertedInput()}
1006:             */
1007:            protected void convertInput() {
1008:                if (typeName == null) {
1009:                    try {
1010:                        convertedInput = convertValue(getInputAsArray());
1011:                    } catch (ConversionException e) {
1012:                        ValidationError error = new ValidationError();
1013:                        if (e.getResourceKey() != null) {
1014:                            error.addMessageKey(e.getResourceKey());
1015:                        }
1016:                        if (e.getTargetType() != null) {
1017:                            error.addMessageKey("ConversionError."
1018:                                    + Classes.simpleName(e.getTargetType()));
1019:                        }
1020:                        error.addMessageKey("ConversionError");
1021:
1022:                        final Locale locale = e.getLocale();
1023:                        if (locale != null) {
1024:                            error.setVariable("locale", locale);
1025:                        }
1026:                        error.setVariable("exception", e);
1027:                        Format format = e.getFormat();
1028:                        if (format instanceof  SimpleDateFormat) {
1029:                            error.setVariable("format",
1030:                                    ((SimpleDateFormat) format)
1031:                                            .toLocalizedPattern());
1032:                        }
1033:
1034:                        error((IValidationError) error);
1035:                    }
1036:                } else {
1037:                    final IConverter converter = getConverter(getType());
1038:                    try {
1039:                        convertedInput = converter.convertToObject(getInput(),
1040:                                getLocale());
1041:                    } catch (ConversionException e) {
1042:                        ValidationError error = new ValidationError();
1043:                        if (e.getResourceKey() != null) {
1044:                            error.addMessageKey(e.getResourceKey());
1045:                        }
1046:                        String simpleName = Classes.simpleName(getType());
1047:                        error.addMessageKey("IConverter." + simpleName);
1048:                        error.addMessageKey("IConverter");
1049:
1050:                        error.setVariable("type", simpleName);
1051:                        final Locale locale = e.getLocale();
1052:                        if (locale != null) {
1053:                            error.setVariable("locale", locale);
1054:                        }
1055:                        error.setVariable("exception", e);
1056:                        Format format = e.getFormat();
1057:                        if (format instanceof  SimpleDateFormat) {
1058:                            error.setVariable("format",
1059:                                    ((SimpleDateFormat) format)
1060:                                            .toLocalizedPattern());
1061:                        }
1062:
1063:                        error((IValidationError) error);
1064:                    }
1065:                }
1066:            }
1067:
1068:            /**
1069:             * Subclasses should overwrite this if the conversion is not done through
1070:             * the type field and the IConverter. <strong>WARNING: this method may be
1071:             * removed in future versions.</strong>
1072:             * 
1073:             * If conversion fails then a ConversionException should be thrown
1074:             * 
1075:             * @param value
1076:             *            The value can be the getInput() or through a cookie
1077:             * 
1078:             * @return The converted value. default returns just the given value
1079:             * @throws ConversionException
1080:             *             If input can't be converted
1081:             */
1082:            protected Object convertValue(String[] value)
1083:                    throws ConversionException {
1084:                return value != null && value.length > 0 && value[0] != null ? value[0]
1085:                        .trim()
1086:                        : null;
1087:            }
1088:
1089:            /**
1090:             * @see org.apache.wicket.Component#getBehaviors(java.lang.Class)
1091:             */
1092:            protected List getBehaviors(Class type) {
1093:                // List
1094:                return super .getBehaviors(type);
1095:            }
1096:
1097:            /**
1098:             * @return Value to return when model value is needed
1099:             */
1100:            protected String getModelValue() {
1101:                return getModelObjectAsString();
1102:            }
1103:
1104:            /**
1105:             * Gets the request parameter for this component as an int.
1106:             * 
1107:             * @return The value in the request for this component
1108:             */
1109:            protected final int inputAsInt() {
1110:                final String string = getInput();
1111:                try {
1112:                    return Integer.parseInt(string);
1113:                } catch (NumberFormatException e) {
1114:                    throw new IllegalArgumentException(
1115:                            exceptionMessage("Internal error.  Request string '"
1116:                                    + string + "' not a valid integer"));
1117:                }
1118:            }
1119:
1120:            /**
1121:             * Gets the request parameter for this component as an int, using the given
1122:             * default in case no corresponding request parameter was found.
1123:             * 
1124:             * @param defaultValue
1125:             *            Default value to return if request does not have an integer
1126:             *            for this component
1127:             * @return The value in the request for this component
1128:             */
1129:            protected final int inputAsInt(final int defaultValue) {
1130:                final String string = getInput();
1131:                if (string != null) {
1132:                    try {
1133:                        return Integer.parseInt(string);
1134:                    } catch (NumberFormatException e) {
1135:                        throw new IllegalArgumentException(
1136:                                exceptionMessage("Request string '" + string
1137:                                        + "' is not a valid integer"));
1138:                    }
1139:                } else {
1140:                    return defaultValue;
1141:                }
1142:            }
1143:
1144:            /**
1145:             * Gets the request parameters for this component as ints.
1146:             * 
1147:             * @return The values in the request for this component
1148:             */
1149:            protected final int[] inputAsIntArray() {
1150:                final String[] strings = getInputAsArray();
1151:                if (strings != null) {
1152:                    final int[] ints = new int[strings.length];
1153:                    for (int i = 0; i < strings.length; i++) {
1154:                        ints[i] = Integer.parseInt(strings[i]);
1155:                    }
1156:                    return ints;
1157:                }
1158:                return null;
1159:            }
1160:
1161:            /**
1162:             * @see org.apache.wicket.Component#internalOnModelChanged()
1163:             */
1164:            protected void internalOnModelChanged() {
1165:                // If the model for this form component changed, we should make it
1166:                // valid again because there can't be any invalid input for it anymore.
1167:                valid();
1168:            }
1169:
1170:            /**
1171:             * Processes the component tag.
1172:             * 
1173:             * @param tag
1174:             *            Tag to modify
1175:             * @see org.apache.wicket.Component#onComponentTag(ComponentTag)
1176:             */
1177:            protected void onComponentTag(final ComponentTag tag) {
1178:                tag.put("name", getInputName());
1179:
1180:                if (!isEnabled() || !isEnableAllowed()) {
1181:                    onDisabled(tag);
1182:                }
1183:
1184:                super .onComponentTag(tag);
1185:            }
1186:
1187:            /**
1188:             * Sets the temporary converted input value to null.
1189:             * 
1190:             * @see org.apache.wicket.Component#onDetach()
1191:             */
1192:            protected void onDetach() {
1193:                super .onDetach();
1194:                convertedInput = null;
1195:            }
1196:
1197:            /**
1198:             * Called by {@link #onComponentTag(ComponentTag)} when the component is
1199:             * disabled. By default, this method will add a disabled="disabled"
1200:             * attribute to the tag. Components may override this method to tweak the
1201:             * tag as they think is fit.
1202:             * 
1203:             * @param tag
1204:             *            the tag that is being rendered
1205:             */
1206:            protected void onDisabled(final ComponentTag tag) {
1207:                tag.put("disabled", "disabled");
1208:            }
1209:
1210:            /**
1211:             * Handle invalidation
1212:             */
1213:            protected void onInvalid() {
1214:            }
1215:
1216:            /**
1217:             * Handle validation
1218:             */
1219:            protected void onValid() {
1220:            }
1221:
1222:            /**
1223:             * @return True if this type of FormComponent can be persisted.
1224:             */
1225:            protected boolean supportsPersistence() {
1226:                return false;
1227:            }
1228:
1229:            /**
1230:             * Checks if the raw input value is not null if this component is required.
1231:             */
1232:            protected final void validateRequired() {
1233:                if (!checkRequired()) {
1234:                    reportRequiredError();
1235:                }
1236:            }
1237:
1238:            /**
1239:             * Reports required error against this component
1240:             */
1241:            private void reportRequiredError() {
1242:                error((IValidationError) new ValidationError()
1243:                        .addMessageKey("Required"));
1244:            }
1245:
1246:            /**
1247:             * Validates this component using the component's validators.
1248:             */
1249:            protected final void validateValidators() {
1250:                final int size = validators_size();
1251:
1252:                final IValidatable validatable = new ValidatableAdapter();
1253:
1254:                int i = 0;
1255:                IValidator validator = null;
1256:
1257:                boolean isNull = getConvertedInput() == null;
1258:
1259:                try {
1260:                    for (i = 0; i < size; i++) {
1261:                        validator = validators_get(i);
1262:
1263:                        if (isNull == false
1264:                                || validator instanceof  INullAcceptingValidator) {
1265:                            validator.validate(validatable);
1266:                        }
1267:                        if (!isValid()) {
1268:                            break;
1269:                        }
1270:                    }
1271:                } catch (Exception e) {
1272:                    throw new WicketRuntimeException("Exception '" + e
1273:                            + "' occurred during validation "
1274:                            + validator.getClass().getName() + " on component "
1275:                            + getPath(), e);
1276:                }
1277:            }
1278:
1279:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.